Ignore:
Timestamp:
Sep 7, 2012, 5:00:31 PM (9 years ago)
Author:
lolbot
Message:

fixed 23 files out of 277:

  • fixed 1270 CR characters
  • fixed 56 trailing spaces
  • fixed 5085 tabs
Location:
trunk/test/Physics
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/test/Physics/Include/BulletCharacterController.h

    r1870 r1888  
    3030{
    3131
    32         namespace phys
    33         {
     32    namespace phys
     33    {
    3434
    3535#ifdef USE_LOL_CTRLR_CHARAC
    3636#ifdef HAVE_PHYS_USE_BULLET
    3737
    38         //SweepCallback used for Swweep Tests.
    39         class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
    40         {
    41         public:
    42                 ClosestNotMeConvexResultCallback(btCollisionObject* NewMe, const vec3& NewUp, float MinSlopeDot) :
    43                                                 btCollisionWorld::ClosestConvexResultCallback(LOL2BTU_VEC3(vec3(.0f)), LOL2BTU_VEC3(vec3(.0f))),
    44                                                 m_me(NewMe),
    45                                                 m_up(NewUp),
    46                                                 m_min_slope_dot(MinSlopeDot) { }
    47 
    48                 virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& ConvexResult, bool NormalInWorld)
    49                 {
    50                         //We hit ourselves, FAIL
    51                         if (ConvexResult.m_hitCollisionObject == m_me)
    52                                 return btScalar(1.f);
    53 
    54                         vec3 WorldHitNomal(.0f);
    55                         if (NormalInWorld)
    56                                 WorldHitNomal = BT2LOL_VEC3(ConvexResult.m_hitNormalLocal);
    57                         else //need to transform Normal into worldspace
    58                         {
    59                                 btVector3 TmpWorldHitNormal = ConvexResult.m_hitCollisionObject->getWorldTransform().getBasis() * ConvexResult.m_hitNormalLocal;
    60                                 WorldHitNomal = BT2LOL_VEC3(TmpWorldHitNormal);
    61                         }
    62 
    63                         float DotUp = dot(m_up, WorldHitNomal);
    64                         //We hit below the accepted slope_dot, FAIL
    65                         if (DotUp < m_min_slope_dot)
    66                                 return btScalar(1.f);
    67 
    68                         //Continue to next.
    69                         return ClosestConvexResultCallback::addSingleResult(ConvexResult, NormalInWorld);
    70                 }
    71         protected:
    72                 btCollisionObject*      m_me;
    73                 const vec3                      m_up;
    74                 float                           m_min_slope_dot;
    75         };
    76 
    77                 ///BulletKinematicCharacterController is an object that supports a sliding motion in a world.
    78                 ///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations.
    79                 ///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user.
    80                 class BulletKinematicCharacterController : public btActionInterface
    81                 {
    82                 public:
    83                         BulletKinematicCharacterController(btPairCachingGhostObject* NewGhostObject, btConvexShape* NewConvexShape, float NewStepHeight, int NewUpAxis=1)
    84                         {
    85                                 m_convex_shape = NewConvexShape;       
    86                                 m_i_up_axis = NewUpAxis;
    87                                 m_ghost_object = NewGhostObject;
    88                                 m_step_height = NewStepHeight;
    89 
    90                                 m_added_margin = 0.02f;
    91                                 m_walk_direction = vec3(.0f, .0f, .0f);
    92                                 m_do_gobject_sweep_test = true;
    93                                 m_turn_angle = .0f;
    94                                 m_use_walk_direction = false; // Should remove walk direction, this doesn't work correctly.
    95                                 m_velocity_time_interval = .0f;
    96                                 m_vertical_velocity = .0f;
    97                                 m_vertical_offset = .0f;
    98                                 m_f_gravity = 9.8f * 3.f; // 3G acceleration.
    99                                 m_fall_speed = 55.f; // Terminal velocity of a sky diver in m/s.
    100                                 m_jump_speed = 10.f; // ?
    101                                 m_was_on_ground = false;
    102                                 m_was_jumping = false;
    103                                 SetMaxSlope(45.f);
    104                         }
    105                         ~BulletKinematicCharacterController() { }
    106 
    107                 protected:
    108 
    109                         static vec3* GetUpAxisDirections()
    110                         {
    111                                 static vec3 sUpAxisDirection[3] = { vec3(1.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f) };
    112        
    113                                 return sUpAxisDirection;
    114                         }
    115 
    116                         //--------------------------
    117                         //CONVENIENCE FUNCTIONS
    118                         //--
    119 
    120                         //Returns the reflection Direction of a ray going 'Direction' hitting a surface with Normal 'Normal' from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html
    121                         vec3 GetReflectedDir(const vec3& Direction, const vec3& Normal)
    122                         {
    123                                 return Direction - (2.f * dot(Direction, Normal) * Normal);
    124                         }
    125                         //Returns the portion of 'direction' that is parallel to 'normal'
    126                         vec3 ProjectDirOnNorm(const vec3& Direction, const vec3& Normal)
    127                         {
    128                                 return Normal * dot(Direction, Normal);
    129                         }
    130                         //Returns the portion of 'Direction' that is perpindicular to 'Normal'
    131                         vec3 ProjectDirOnNormPerpindicular(const vec3& Direction, const vec3& Normal)
    132                         {
    133                                 return Direction - ProjectDirOnNorm(Direction, Normal);
    134                         }
    135                         //Returns Ghost Object. -duh-
    136                         btPairCachingGhostObject* GetGhostObject()
    137                         {
    138                                 return m_ghost_object;
    139                         }
    140 
    141                         //"Real" war functions
    142                         bool RecoverFromPenetration(btCollisionWorld* CollisionWorld);
    143                         void UpdateTargetOnHit(const vec3& hit_normal, float TangentMag = .0f, float NormalMag = 1.f);
    144                         void DoMove(btCollisionWorld* CollisionWorld, const vec3& MoveStep, float DeltaTime);
    145 
    146                 public:
    147                         ///btActionInterface interface : KEEP IN camelCase
    148                         virtual void updateAction(btCollisionWorld* CollisionWorld, float deltaTime)
    149                         {
    150                                 PreStep(CollisionWorld);
    151                                 PlayerStep(CollisionWorld, deltaTime);
    152                         }
    153 
    154                         //not in the interface, but called above
    155                         void PreStep(btCollisionWorld* CollisionWorld);
    156                         void PlayerStep(btCollisionWorld* CollisionWorld, float DeltaTime);
    157 
    158                         ///btActionInterface interface : KEEP IN camelCase
    159                         void debugDraw(btIDebugDraw* debugDrawer) { }
    160                        
    161                         void SetUpAxis(int NewAxis)
    162                         {
    163                                 if (NewAxis < 0)
    164                                         NewAxis = 0;
    165                                 if (NewAxis > 2)
    166                                         NewAxis = 2;
    167                                 m_i_up_axis = NewAxis;
    168                         }
    169 
    170                         //!!!!!! SHOULD DITCH THAT !!!!!!
    171                         //This should probably be called setPositionIncrementPerSimulatorStep.
    172                         //This is neither a Direction nor a velocity, but the amount to
    173                         //increment the position each simulation iteration, regardless
    174                         //of DeltaTime.
    175                         //This call will Reset any velocity set by SetVelocityForTimeInterval().
    176                         virtual void SetWalkDirection(const vec3& walkDirection)
    177                         {
    178                                 m_use_walk_direction = true;
    179                                 m_walk_direction = walkDirection;
    180                                 m_normalized_direction = normalize(m_walk_direction);
    181                         }
    182 
    183                         //Caller provides a velocity with which the character should MoveStep for
    184                         //the given time period.  After the time period, velocity is Reset
    185                         //to zero.
    186                         //This call will Reset any walk Direction set by SetWalkDirection().
    187                         //Negative time intervals will result in no motion.
    188                         virtual void SetVelocityForTimeInterval(const vec3& velocity, float timeInterval)
    189                         {
    190                                 m_use_walk_direction = false;
    191                                 m_walk_direction = velocity;
    192                                 m_normalized_direction = normalize(m_walk_direction);
    193                                 m_velocity_time_interval = timeInterval;
    194                         }
    195 
    196                         //Usefulness ?
    197                         void Reset() { }
    198                         void Warp(const vec3& NewOrigin)
    199                         {
    200                                 btTransform NewTransform;
    201                                 NewTransform.setIdentity();
    202                                 NewTransform.setOrigin(LOL2BTU_VEC3(NewOrigin));
    203                                 m_ghost_object->setWorldTransform(NewTransform);
    204                         }
    205 
    206                         //External Setup
    207                         //--
    208 
    209                         void SetFallSpeed(float NewFallSpeed)                   { m_fall_speed = NewFallSpeed; }
    210                         void SetJumpSpeed(float NewJumpSpeed)                   { m_jump_speed = NewJumpSpeed; }
    211                         void SetMaxJumpHeight(float NewMaxJumpHeight)   { m_max_jump_height = NewMaxJumpHeight; }
    212 
    213                         //Jump logic will go in EasyCC
    214                         bool CanJump() const                                                    { return OnGround(); }
    215                         void Jump();
    216 
    217                         //NewGravity functions
    218                         void SetGravity(float NewGravity)                               { m_f_gravity = NewGravity; }
    219                         float GetGravity() const                                                { return m_f_gravity; }
    220 
    221                         //The max slope determines the maximum angle that the controller can walk up.
    222                         //The slope angle is measured in radians.
    223                         void SetMaxSlope(float NewSlopeRadians)                 { m_max_slope_radians = NewSlopeRadians; m_max_slope_cosine = lol::cos(NewSlopeRadians); }
    224                         float GetMaxSlope() const                                               { return m_max_slope_radians; }
    225 
    226                         void SetUseGhostSweepTest(bool UseGObjectSweepTest) { m_do_gobject_sweep_test = UseGObjectSweepTest; }
    227 
    228                         bool OnGround() const                                                   { return m_vertical_velocity == .0f && m_vertical_offset == .0f; }
    229 
    230                 private:
    231 
    232                         btPairCachingGhostObject*       m_ghost_object;
    233                         btConvexShape*                          m_convex_shape; //is also in m_ghost_object, but it needs to be convex, so we store it here to avoid upcast
    234 
    235                         //keep track of the contact manifolds
    236                         btManifoldArray                         m_manifold_array;
    237 
    238                         float                                           m_half_height;
    239                         float                                           m_velocity_time_interval;
    240                         float                                           m_vertical_velocity;
    241                         float                                           m_vertical_offset;
    242                         float                                           m_fall_speed;
    243                         float                                           m_jump_speed;
    244                         float                                           m_max_jump_height;
    245                         float                                           m_max_slope_radians; // Slope angle that is set (used for returning the exact value)
    246                         float                                           m_max_slope_cosine;  // Cosine equivalent of m_max_slope_radians (calculated once when set, for optimization)
    247                         float                                           m_f_gravity;
    248                         float                                           m_turn_angle;
    249                         float                                           m_step_height;
    250                         float                                           m_added_margin;//@todo: remove this and fix the code
    251 
    252                         ///this is the desired walk Direction, set by the user
    253                         vec3                                            m_walk_direction;
    254                         vec3                                            m_normalized_direction;
    255 
    256                         //some internal variables
    257                         vec3                                            m_current_position;
    258                         float                                           m_current_step_offset;
    259                         vec3                                            m_target_position;
    260 
    261                         vec3                                            m_touching_normal;
    262                         bool                                            m_touching_contact;
    263 
    264                         bool                                            m_was_on_ground;
    265                         bool                                            m_was_jumping;
    266                         bool                                            m_do_gobject_sweep_test;
    267                         bool                                            m_use_walk_direction;
    268                         int                                                     m_i_up_axis;
    269 
    270                         //---------------------------------------------------------------------
    271                         //NEW INTERNAL VARS
    272                         //---------------------------------------------------------------------
    273 
    274                         //Gravity in vec3
    275                         vec3                                            m_gravity;
    276 
    277                         //Current Velocity
    278                         vec3                                            m_velocity;
    279                 };
     38    //SweepCallback used for Swweep Tests.
     39    class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
     40    {
     41    public:
     42        ClosestNotMeConvexResultCallback(btCollisionObject* NewMe, const vec3& NewUp, float MinSlopeDot) :
     43                        btCollisionWorld::ClosestConvexResultCallback(LOL2BTU_VEC3(vec3(.0f)), LOL2BTU_VEC3(vec3(.0f))),
     44                        m_me(NewMe),
     45                        m_up(NewUp),
     46                        m_min_slope_dot(MinSlopeDot) { }
     47
     48        virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& ConvexResult, bool NormalInWorld)
     49        {
     50            //We hit ourselves, FAIL
     51            if (ConvexResult.m_hitCollisionObject == m_me)
     52                return btScalar(1.f);
     53
     54            vec3 WorldHitNomal(.0f);
     55            if (NormalInWorld)
     56                WorldHitNomal = BT2LOL_VEC3(ConvexResult.m_hitNormalLocal);
     57            else //need to transform Normal into worldspace
     58            {
     59                btVector3 TmpWorldHitNormal = ConvexResult.m_hitCollisionObject->getWorldTransform().getBasis() * ConvexResult.m_hitNormalLocal;
     60                WorldHitNomal = BT2LOL_VEC3(TmpWorldHitNormal);
     61            }
     62
     63            float DotUp = dot(m_up, WorldHitNomal);
     64            //We hit below the accepted slope_dot, FAIL
     65            if (DotUp < m_min_slope_dot)
     66                return btScalar(1.f);
     67
     68            //Continue to next.
     69            return ClosestConvexResultCallback::addSingleResult(ConvexResult, NormalInWorld);
     70        }
     71    protected:
     72        btCollisionObject*    m_me;
     73        const vec3            m_up;
     74        float                m_min_slope_dot;
     75    };
     76
     77        ///BulletKinematicCharacterController is an object that supports a sliding motion in a world.
     78        ///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations.
     79        ///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user.
     80        class BulletKinematicCharacterController : public btActionInterface
     81        {
     82        public:
     83            BulletKinematicCharacterController(btPairCachingGhostObject* NewGhostObject, btConvexShape* NewConvexShape, float NewStepHeight, int NewUpAxis=1)
     84            {
     85                m_convex_shape = NewConvexShape;
     86                m_i_up_axis = NewUpAxis;
     87                m_ghost_object = NewGhostObject;
     88                m_step_height = NewStepHeight;
     89
     90                m_added_margin = 0.02f;
     91                m_walk_direction = vec3(.0f, .0f, .0f);
     92                m_do_gobject_sweep_test = true;
     93                m_turn_angle = .0f;
     94                m_use_walk_direction = false; // Should remove walk direction, this doesn't work correctly.
     95                m_velocity_time_interval = .0f;
     96                m_vertical_velocity = .0f;
     97                m_vertical_offset = .0f;
     98                m_f_gravity = 9.8f * 3.f; // 3G acceleration.
     99                m_fall_speed = 55.f; // Terminal velocity of a sky diver in m/s.
     100                m_jump_speed = 10.f; // ?
     101                m_was_on_ground = false;
     102                m_was_jumping = false;
     103                SetMaxSlope(45.f);
     104            }
     105            ~BulletKinematicCharacterController() { }
     106
     107        protected:
     108
     109            static vec3* GetUpAxisDirections()
     110            {
     111                static vec3 sUpAxisDirection[3] = { vec3(1.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f) };
     112
     113                return sUpAxisDirection;
     114            }
     115
     116            //--------------------------
     117            //CONVENIENCE FUNCTIONS
     118            //--
     119
     120            //Returns the reflection Direction of a ray going 'Direction' hitting a surface with Normal 'Normal' from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html
     121            vec3 GetReflectedDir(const vec3& Direction, const vec3& Normal)
     122            {
     123                return Direction - (2.f * dot(Direction, Normal) * Normal);
     124            }
     125            //Returns the portion of 'direction' that is parallel to 'normal'
     126            vec3 ProjectDirOnNorm(const vec3& Direction, const vec3& Normal)
     127            {
     128                return Normal * dot(Direction, Normal);
     129            }
     130            //Returns the portion of 'Direction' that is perpindicular to 'Normal'
     131            vec3 ProjectDirOnNormPerpindicular(const vec3& Direction, const vec3& Normal)
     132            {
     133                return Direction - ProjectDirOnNorm(Direction, Normal);
     134            }
     135            //Returns Ghost Object. -duh-
     136            btPairCachingGhostObject* GetGhostObject()
     137            {
     138                return m_ghost_object;
     139            }
     140
     141            //"Real" war functions
     142            bool RecoverFromPenetration(btCollisionWorld* CollisionWorld);
     143            void UpdateTargetOnHit(const vec3& hit_normal, float TangentMag = .0f, float NormalMag = 1.f);
     144            void DoMove(btCollisionWorld* CollisionWorld, const vec3& MoveStep, float DeltaTime);
     145
     146        public:
     147            ///btActionInterface interface : KEEP IN camelCase
     148            virtual void updateAction(btCollisionWorld* CollisionWorld, float deltaTime)
     149            {
     150                PreStep(CollisionWorld);
     151                PlayerStep(CollisionWorld, deltaTime);
     152            }
     153
     154            //not in the interface, but called above
     155            void PreStep(btCollisionWorld* CollisionWorld);
     156            void PlayerStep(btCollisionWorld* CollisionWorld, float DeltaTime);
     157
     158            ///btActionInterface interface : KEEP IN camelCase
     159            void debugDraw(btIDebugDraw* debugDrawer) { }
     160
     161            void SetUpAxis(int NewAxis)
     162            {
     163                if (NewAxis < 0)
     164                    NewAxis = 0;
     165                if (NewAxis > 2)
     166                    NewAxis = 2;
     167                m_i_up_axis = NewAxis;
     168            }
     169
     170            //!!!!!! SHOULD DITCH THAT !!!!!!
     171            //This should probably be called setPositionIncrementPerSimulatorStep.
     172            //This is neither a Direction nor a velocity, but the amount to
     173            //increment the position each simulation iteration, regardless
     174            //of DeltaTime.
     175            //This call will Reset any velocity set by SetVelocityForTimeInterval().
     176            virtual void SetWalkDirection(const vec3& walkDirection)
     177            {
     178                m_use_walk_direction = true;
     179                m_walk_direction = walkDirection;
     180                m_normalized_direction = normalize(m_walk_direction);
     181            }
     182
     183            //Caller provides a velocity with which the character should MoveStep for
     184            //the given time period.  After the time period, velocity is Reset
     185            //to zero.
     186            //This call will Reset any walk Direction set by SetWalkDirection().
     187            //Negative time intervals will result in no motion.
     188            virtual void SetVelocityForTimeInterval(const vec3& velocity, float timeInterval)
     189            {
     190                m_use_walk_direction = false;
     191                m_walk_direction = velocity;
     192                m_normalized_direction = normalize(m_walk_direction);
     193                m_velocity_time_interval = timeInterval;
     194            }
     195
     196            //Usefulness ?
     197            void Reset() { }
     198            void Warp(const vec3& NewOrigin)
     199            {
     200                btTransform NewTransform;
     201                NewTransform.setIdentity();
     202                NewTransform.setOrigin(LOL2BTU_VEC3(NewOrigin));
     203                m_ghost_object->setWorldTransform(NewTransform);
     204            }
     205
     206            //External Setup
     207            //--
     208
     209            void SetFallSpeed(float NewFallSpeed)            { m_fall_speed = NewFallSpeed; }
     210            void SetJumpSpeed(float NewJumpSpeed)            { m_jump_speed = NewJumpSpeed; }
     211            void SetMaxJumpHeight(float NewMaxJumpHeight)    { m_max_jump_height = NewMaxJumpHeight; }
     212
     213            //Jump logic will go in EasyCC
     214            bool CanJump() const                            { return OnGround(); }
     215            void Jump();
     216
     217            //NewGravity functions
     218            void SetGravity(float NewGravity)                { m_f_gravity = NewGravity; }
     219            float GetGravity() const                        { return m_f_gravity; }
     220
     221            //The max slope determines the maximum angle that the controller can walk up.
     222            //The slope angle is measured in radians.
     223            void SetMaxSlope(float NewSlopeRadians)            { m_max_slope_radians = NewSlopeRadians; m_max_slope_cosine = lol::cos(NewSlopeRadians); }
     224            float GetMaxSlope() const                        { return m_max_slope_radians; }
     225
     226            void SetUseGhostSweepTest(bool UseGObjectSweepTest) { m_do_gobject_sweep_test = UseGObjectSweepTest; }
     227
     228            bool OnGround() const                            { return m_vertical_velocity == .0f && m_vertical_offset == .0f; }
     229
     230        private:
     231
     232            btPairCachingGhostObject*    m_ghost_object;
     233            btConvexShape*                m_convex_shape; //is also in m_ghost_object, but it needs to be convex, so we store it here to avoid upcast
     234
     235            //keep track of the contact manifolds
     236            btManifoldArray                m_manifold_array;
     237
     238            float                        m_half_height;
     239            float                        m_velocity_time_interval;
     240            float                        m_vertical_velocity;
     241            float                        m_vertical_offset;
     242            float                        m_fall_speed;
     243            float                        m_jump_speed;
     244            float                        m_max_jump_height;
     245            float                        m_max_slope_radians; // Slope angle that is set (used for returning the exact value)
     246            float                        m_max_slope_cosine;  // Cosine equivalent of m_max_slope_radians (calculated once when set, for optimization)
     247            float                        m_f_gravity;
     248            float                        m_turn_angle;
     249            float                        m_step_height;
     250            float                        m_added_margin;//@todo: remove this and fix the code
     251
     252            ///this is the desired walk Direction, set by the user
     253            vec3                        m_walk_direction;
     254            vec3                        m_normalized_direction;
     255
     256            //some internal variables
     257            vec3                        m_current_position;
     258            float                         m_current_step_offset;
     259            vec3                        m_target_position;
     260
     261            vec3                        m_touching_normal;
     262            bool                        m_touching_contact;
     263
     264            bool                        m_was_on_ground;
     265            bool                         m_was_jumping;
     266            bool                        m_do_gobject_sweep_test;
     267            bool                        m_use_walk_direction;
     268            int                            m_i_up_axis;
     269
     270            //---------------------------------------------------------------------
     271            //NEW INTERNAL VARS
     272            //---------------------------------------------------------------------
     273
     274            //Gravity in vec3
     275            vec3                        m_gravity;
     276
     277            //Current Velocity
     278            vec3                        m_velocity;
     279        };
    280280
    281281#endif // HAVE_PHYS_USE_BULLET
    282282#endif // USE_LOL_CTRLR_CHARAC
    283283
    284         } /* namespace phys */
     284    } /* namespace phys */
    285285
    286286} /* namespace lol */
  • trunk/test/Physics/Include/EasyCharacterController.h

    r1870 r1888  
    3535
    3636class EasyCharacterController : public EasyPhysic,
    37                                                                 public Entity
     37                                public Entity
    3838{
    3939
    40         friend class Simulation;
    41         friend class EasyPhysic;
     40    friend class Simulation;
     41    friend class EasyPhysic;
    4242
    4343#ifdef HAVE_PHYS_USE_BULLET
    4444
    4545public:
    46         EasyCharacterController(WorldEntity* NewOwnerEntity) :
    47                 EasyPhysic(NewOwnerEntity),
    48                 m_pair_caching_object(NULL),
    49                 m_character(NULL),
    50                 m_step_height(.0f),
    51                 m_base_is_updating(false),
    52                 m_base_cached_movement(vec3(0.f)),
    53                 m_frame_cached_movement(vec3(0.f)),
    54                 m_walk_velocity(vec3(0.f)),
    55                 m_current_velocity(vec3(0.f))
    56         {
    57                 m_gamegroup = GAMEGROUP_EZP_CHAR_CTRLR;
    58                 m_up_axis = 1;
    59                 m_gravity = vec3(.0f, -9.81f, .0f);
    60                 m_walk_velocity_damping = 0.2f;
    61         }
    62         ~EasyCharacterController()
    63         {
    64                 delete m_character;
    65         }
     46    EasyCharacterController(WorldEntity* NewOwnerEntity) :
     47        EasyPhysic(NewOwnerEntity),
     48        m_pair_caching_object(NULL),
     49        m_character(NULL),
     50        m_step_height(.0f),
     51        m_base_is_updating(false),
     52        m_base_cached_movement(vec3(0.f)),
     53        m_frame_cached_movement(vec3(0.f)),
     54        m_walk_velocity(vec3(0.f)),
     55        m_current_velocity(vec3(0.f))
     56    {
     57        m_gamegroup = GAMEGROUP_EZP_CHAR_CTRLR;
     58        m_up_axis = 1;
     59        m_gravity = vec3(.0f, -9.81f, .0f);
     60        m_walk_velocity_damping = 0.2f;
     61    }
     62    ~EasyCharacterController()
     63    {
     64        delete m_character;
     65    }
    6666
    67         virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false);
    68         virtual void InitBodyToGhost();
    69         virtual void AddToSimulation(class Simulation* current_simulation);
    70         virtual void RemoveFromSimulation(class Simulation* current_simulation);
    71         virtual void SetMovementForFrame(vec3 const &MoveQuantity);
    72         virtual void Jump();
     67    virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false);
     68    virtual void InitBodyToGhost();
     69    virtual void AddToSimulation(class Simulation* current_simulation);
     70    virtual void RemoveFromSimulation(class Simulation* current_simulation);
     71    virtual void SetMovementForFrame(vec3 const &MoveQuantity);
     72    virtual void Jump();
    7373
    74         virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation);
     74    virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation);
    7575protected:
    76         virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix);
    77         virtual char const *GetName();
     76    virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix);
     77    virtual char const *GetName();
    7878public:
    79         virtual void TickGame(float seconds);
     79    virtual void TickGame(float seconds);
    8080
    8181protected:
    8282
    83         virtual btGhostObject* GetGhostObjectInstance();
     83    virtual btGhostObject* GetGhostObjectInstance();
    8484
    85         btPairCachingGhostObject*               m_pair_caching_object;
    86         //btKinematicCharacterController*       m_character;
    87         BulletKinematicCharacterController* m_character;
     85    btPairCachingGhostObject*        m_pair_caching_object;
     86    //btKinematicCharacterController*    m_character;
     87    BulletKinematicCharacterController* m_character;
    8888
    89         float                                                   m_step_height;
    90         int                                                             m_up_axis;
    91         bool                                                    m_base_is_updating;
    92         vec3                                                    m_base_cached_movement;
    93         vec3                                                    m_frame_cached_movement;
     89    float                            m_step_height;
     90    int                                m_up_axis;
     91    bool                            m_base_is_updating;
     92    vec3                            m_base_cached_movement;
     93    vec3                            m_frame_cached_movement;
    9494
    95         //----
    96         float                                                   m_walk_velocity_damping;
     95    //----
     96    float                            m_walk_velocity_damping;
    9797
    98         //----
    99         vec3                                                    m_gravity;
     98    //----
     99    vec3                            m_gravity;
    100100
    101         //----
    102         vec3                                                    m_walk_velocity;
    103         vec3                                                    m_current_velocity;
     101    //----
     102    vec3                            m_walk_velocity;
     103    vec3                            m_current_velocity;
    104104
    105105#else  // NO PHYSIC IMPLEMENTATION
    106106
    107         virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false) { }
    108         virtual void InitBodyToGhost() { }
    109         virtual void AddToSimulation(class Simulation* current_simulation) { }
    110         virtual void RemoveFromSimulation(class Simulation* current_simulation) { }
    111         virtual void SetMovementForFrame(vec3 const &MoveQuantity) { }
     107    virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false) { }
     108    virtual void InitBodyToGhost() { }
     109    virtual void AddToSimulation(class Simulation* current_simulation) { }
     110    virtual void RemoveFromSimulation(class Simulation* current_simulation) { }
     111    virtual void SetMovementForFrame(vec3 const &MoveQuantity) { }
    112112
    113113#endif // PHYSIC IMPLEMENTATION
  • trunk/test/Physics/Include/EasyConstraint.h

    r1782 r1888  
    3232{
    3333
    34         friend class Simulation;
    35         friend class EasyPhysic;
     34    friend class Simulation;
     35    friend class EasyPhysic;
    3636
    3737#ifdef HAVE_PHYS_USE_BULLET
    3838
    3939public:
    40         EasyConstraint() :
    41                 m_typed_constraint(NULL),
    42                 m_p2p_constraint(NULL),
    43                 m_hinge_constraint(NULL),
    44                 m_slider_constraint(NULL),
    45                 m_cone_twist_constraint(NULL),
    46                 m_6dof_constraint(NULL),
    47                 m_owner_simulation(NULL),
    48                 m_a_physobj(NULL),
    49                 m_b_physobj(NULL),
    50                 m_a_transform(lol::mat4(1.f)),
    51                 m_b_transform(lol::mat4(1.f)),
    52                 m_using_ref_a(false),
    53                 m_disable_a2b_collision(false)
    54 
    55         {
    56         }
    57         ~EasyConstraint()
    58         {
    59                 delete m_typed_constraint;
    60                 m_p2p_constraint = NULL;
    61                 m_hinge_constraint = NULL;
    62                 m_slider_constraint = NULL;
    63                 m_cone_twist_constraint = NULL;
    64                 m_6dof_constraint = NULL;
    65         }
    66 
    67         void AddToSimulation(class Simulation* current_simulation);
    68         void RemoveFromSimulation(class Simulation* current_simulation);
     40    EasyConstraint() :
     41        m_typed_constraint(NULL),
     42        m_p2p_constraint(NULL),
     43        m_hinge_constraint(NULL),
     44        m_slider_constraint(NULL),
     45        m_cone_twist_constraint(NULL),
     46        m_6dof_constraint(NULL),
     47        m_owner_simulation(NULL),
     48        m_a_physobj(NULL),
     49        m_b_physobj(NULL),
     50        m_a_transform(lol::mat4(1.f)),
     51        m_b_transform(lol::mat4(1.f)),
     52        m_using_ref_a(false),
     53        m_disable_a2b_collision(false)
     54
     55    {
     56    }
     57    ~EasyConstraint()
     58    {
     59        delete m_typed_constraint;
     60        m_p2p_constraint = NULL;
     61        m_hinge_constraint = NULL;
     62        m_slider_constraint = NULL;
     63        m_cone_twist_constraint = NULL;
     64        m_6dof_constraint = NULL;
     65    }
     66
     67    void AddToSimulation(class Simulation* current_simulation);
     68    void RemoveFromSimulation(class Simulation* current_simulation);
    6969
    7070private:
    7171
    72         //check if Init can be done
    73         bool CanProceedWithInit()
    74         {
    75                 if (!m_a_physobj || !m_b_physobj)
    76                         return false;
    77 
    78                 if (!m_a_physobj->m_rigid_body || !m_b_physobj->m_rigid_body)
    79                         return false;
    80 
    81                 return true;
    82         }
    83 
    84         //-------------------------------------------------------------------------
    85         //Init constraint functions
    86         //--
    87         void CustomInitConstraintToPoint2Point()
    88         {
    89                 m_p2p_constraint = new btPoint2PointConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
    90                                                                                                                 LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT));
    91                 m_typed_constraint = m_p2p_constraint;
    92         }
    93 
    94         void CustomInitConstraintToHinge()
    95         {
    96                 m_hinge_constraint = new btHingeConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
    97                                                                                                                 btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
    98                                                                                                                 btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)),
    99                                                                                                                 m_using_ref_a);
    100                 m_typed_constraint = m_hinge_constraint;
    101         }
    102 
    103         void CustomInitConstraintToSlider()
    104         {
    105                 m_slider_constraint = new btSliderConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
    106                                                                                                                 btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
    107                                                                                                                 btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)),
    108                                                                                                                 m_using_ref_a);
    109                 m_typed_constraint = m_slider_constraint;
    110         }
    111 
    112         void CustomInitConstraintToConeTwist()
    113         {
    114                 m_cone_twist_constraint = new btConeTwistConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
    115                                                                                                                 btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
    116                                                                                                                 btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)));
    117                 m_typed_constraint = m_cone_twist_constraint;
    118         }
    119 
    120         void CustomInitConstraintTo6Dof()
    121         {
    122                 m_6dof_constraint = new btGeneric6DofConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
    123                                                                                                                 btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
    124                                                                                                                 btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)),
    125                                                                                                                 m_using_ref_a);
    126                 m_typed_constraint = m_6dof_constraint;
    127         }
    128 
    129         btTypedConstraint*                      m_typed_constraint;
    130         btPoint2PointConstraint*        m_p2p_constraint;
    131         btHingeConstraint*                      m_hinge_constraint;
    132         btSliderConstraint*                     m_slider_constraint;
    133         btConeTwistConstraint*          m_cone_twist_constraint;
    134         btGeneric6DofConstraint*        m_6dof_constraint;
     72    //check if Init can be done
     73    bool CanProceedWithInit()
     74    {
     75        if (!m_a_physobj || !m_b_physobj)
     76            return false;
     77
     78        if (!m_a_physobj->m_rigid_body || !m_b_physobj->m_rigid_body)
     79            return false;
     80
     81        return true;
     82    }
     83
     84    //-------------------------------------------------------------------------
     85    //Init constraint functions
     86    //--
     87    void CustomInitConstraintToPoint2Point()
     88    {
     89        m_p2p_constraint = new btPoint2PointConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
     90                                                        LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT));
     91        m_typed_constraint = m_p2p_constraint;
     92    }
     93
     94    void CustomInitConstraintToHinge()
     95    {
     96        m_hinge_constraint = new btHingeConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
     97                                                        btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
     98                                                        btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)),
     99                                                        m_using_ref_a);
     100        m_typed_constraint = m_hinge_constraint;
     101    }
     102
     103    void CustomInitConstraintToSlider()
     104    {
     105        m_slider_constraint = new btSliderConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
     106                                                        btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
     107                                                        btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)),
     108                                                        m_using_ref_a);
     109        m_typed_constraint = m_slider_constraint;
     110    }
     111
     112    void CustomInitConstraintToConeTwist()
     113    {
     114        m_cone_twist_constraint = new btConeTwistConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
     115                                                        btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
     116                                                        btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)));
     117        m_typed_constraint = m_cone_twist_constraint;
     118    }
     119
     120    void CustomInitConstraintTo6Dof()
     121    {
     122        m_6dof_constraint = new btGeneric6DofConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
     123                                                        btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
     124                                                        btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)),
     125                                                        m_using_ref_a);
     126        m_typed_constraint = m_6dof_constraint;
     127    }
     128
     129    btTypedConstraint*            m_typed_constraint;
     130    btPoint2PointConstraint*    m_p2p_constraint;
     131    btHingeConstraint*            m_hinge_constraint;
     132    btSliderConstraint*            m_slider_constraint;
     133    btConeTwistConstraint*        m_cone_twist_constraint;
     134    btGeneric6DofConstraint*    m_6dof_constraint;
    135135
    136136#else  // NO PHYSIC IMPLEMENTATION
    137137
    138138public:
    139         EasyConstraint() :
    140                 m_a_physobj(NULL),
    141                 m_b_physobj(NULL),
    142                 m_a_transform(lol::mat4(1.f)),
    143                 m_b_transform(lol::mat4(1.f)),
    144                 m_using_ref_a(false),
    145                 m_disable_a2b_collision(false)
    146         {
    147         }
     139    EasyConstraint() :
     140        m_a_physobj(NULL),
     141        m_b_physobj(NULL),
     142        m_a_transform(lol::mat4(1.f)),
     143        m_b_transform(lol::mat4(1.f)),
     144        m_using_ref_a(false),
     145        m_disable_a2b_collision(false)
     146    {
     147    }
    148148
    149149private:
    150150
    151         void AddToSimulation(class Simulation* current_simulation) { }
    152         void RemoveFromSimulation(class Simulation* current_simulation) { }
    153 
    154         //check if Init can be done
    155         bool CanProceedWithInit() { return false; }
    156         void CustomInitConstraintToPoint2Point() { }
    157         void CustomInitConstraintToHinge() { }
    158         void CustomInitConstraintToSlider() { }
    159         void CustomInitConstraintToConeTwist() { }
    160         void CustomInitConstraintTo6Dof() { }
     151    void AddToSimulation(class Simulation* current_simulation) { }
     152    void RemoveFromSimulation(class Simulation* current_simulation) { }
     153
     154    //check if Init can be done
     155    bool CanProceedWithInit() { return false; }
     156    void CustomInitConstraintToPoint2Point() { }
     157    void CustomInitConstraintToHinge() { }
     158    void CustomInitConstraintToSlider() { }
     159    void CustomInitConstraintToConeTwist() { }
     160    void CustomInitConstraintTo6Dof() { }
    161161
    162162#endif // PHYSIC IMPLEMENTATION
    163163
    164164public:
    165         void InitConstraintToPoint2Point()      { if (CanProceedWithInit()) CustomInitConstraintToPoint2Point(); }
    166         void InitConstraintToHinge()            { if (CanProceedWithInit()) CustomInitConstraintToHinge(); }
    167         void InitConstraintToSlider()           { if (CanProceedWithInit()) CustomInitConstraintToSlider(); }
    168         void InitConstraintToConeTwist()        { if (CanProceedWithInit()) CustomInitConstraintToConeTwist(); }
    169         void InitConstraintTo6Dof()                     { if (CanProceedWithInit()) CustomInitConstraintTo6Dof(); }
    170 
    171         //Set given physic object to the proper slot.
    172         void SetPhysObjA(EasyPhysic* NewPhysObj, lol::mat4 NewTransform) { SetPhysObj(false, NewPhysObj, NewTransform); }
    173         void SetPhysObjB(EasyPhysic* NewPhysObj, lol::mat4 NewTransform) { SetPhysObj(true, NewPhysObj, NewTransform); }
    174         void SetPhysObj(bool SetToB, EasyPhysic* NewPhysObj, lol::mat4 NewTransform)
    175         {
    176                 if (SetToB)
    177                 {
    178                         m_b_physobj = NewPhysObj;
    179                         m_b_transform = NewTransform;
    180                 }
    181                 else
    182                 {
    183                         m_a_physobj = NewPhysObj;
    184                         m_a_transform = NewTransform;
    185                 }
    186         }
    187 
    188         //Set whether or not the physic engine should use the A object as the reference (most constraint transform are local).
    189         void SetRefAsA(bool NewUseRefA)
    190         {
    191                 m_using_ref_a = NewUseRefA;
    192         }
    193 
    194         //Set whether or not to disable the collision between the bodies
    195         void DisableCollisionBetweenObjs(bool DisableCollision)
    196         {
    197                 m_disable_a2b_collision = DisableCollision;
    198         }
     165    void InitConstraintToPoint2Point()    { if (CanProceedWithInit()) CustomInitConstraintToPoint2Point(); }
     166    void InitConstraintToHinge()        { if (CanProceedWithInit()) CustomInitConstraintToHinge(); }
     167    void InitConstraintToSlider()        { if (CanProceedWithInit()) CustomInitConstraintToSlider(); }
     168    void InitConstraintToConeTwist()    { if (CanProceedWithInit()) CustomInitConstraintToConeTwist(); }
     169    void InitConstraintTo6Dof()            { if (CanProceedWithInit()) CustomInitConstraintTo6Dof(); }
     170
     171    //Set given physic object to the proper slot.
     172    void SetPhysObjA(EasyPhysic* NewPhysObj, lol::mat4 NewTransform) { SetPhysObj(false, NewPhysObj, NewTransform); }
     173    void SetPhysObjB(EasyPhysic* NewPhysObj, lol::mat4 NewTransform) { SetPhysObj(true, NewPhysObj, NewTransform); }
     174    void SetPhysObj(bool SetToB, EasyPhysic* NewPhysObj, lol::mat4 NewTransform)
     175    {
     176        if (SetToB)
     177        {
     178            m_b_physobj = NewPhysObj;
     179            m_b_transform = NewTransform;
     180        }
     181        else
     182        {
     183            m_a_physobj = NewPhysObj;
     184            m_a_transform = NewTransform;
     185        }
     186    }
     187
     188    //Set whether or not the physic engine should use the A object as the reference (most constraint transform are local).
     189    void SetRefAsA(bool NewUseRefA)
     190    {
     191        m_using_ref_a = NewUseRefA;
     192    }
     193
     194    //Set whether or not to disable the collision between the bodies
     195    void DisableCollisionBetweenObjs(bool DisableCollision)
     196    {
     197        m_disable_a2b_collision = DisableCollision;
     198    }
    199199
    200200private:
    201         Simulation*                                     m_owner_simulation;
    202         EasyPhysic*                                     m_a_physobj;
    203         EasyPhysic*                                     m_b_physobj;
    204         lol::mat4                                       m_a_transform;
    205         lol::mat4                                       m_b_transform;
    206         bool                                            m_using_ref_a;
    207         bool                                            m_disable_a2b_collision;
     201    Simulation*                    m_owner_simulation;
     202    EasyPhysic*                    m_a_physobj;
     203    EasyPhysic*                    m_b_physobj;
     204    lol::mat4                    m_a_transform;
     205    lol::mat4                    m_b_transform;
     206    bool                        m_using_ref_a;
     207    bool                        m_disable_a2b_collision;
    208208
    209209};
  • trunk/test/Physics/Include/EasyPhysics.h

    r1819 r1888  
    3434{
    3535
    36         friend class Simulation;
    37         friend class EasyConstraint;
     36    friend class Simulation;
     37    friend class EasyConstraint;
    3838
    3939#ifdef HAVE_PHYS_USE_BULLET
    4040
    4141public:
    42         EasyPhysic(WorldEntity* NewOwnerEntity);
    43         ~EasyPhysic();
     42    EasyPhysic(WorldEntity* NewOwnerEntity);
     43    ~EasyPhysic();
    4444
    45         virtual void SetShapeToBox(lol::vec3& box_size);
    46         virtual void SetShapeToSphere(float radius);
    47         virtual void SetShapeToCone(float radius, float height);
    48         virtual void SetShapeToCylinder(lol::vec3& cyl_size);
    49         virtual void SetShapeToCapsule(float radius, float height);
     45    virtual void SetShapeToBox(lol::vec3& box_size);
     46    virtual void SetShapeToSphere(float radius);
     47    virtual void SetShapeToCone(float radius, float height);
     48    virtual void SetShapeToCylinder(lol::vec3& cyl_size);
     49    virtual void SetShapeToCapsule(float radius, float height);
    5050
    51         virtual bool CanChangeCollisionChannel() { return (m_rigid_body == NULL); }
    52         virtual mat4 GetTransform();
    53         virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f)));
     51    virtual bool CanChangeCollisionChannel() { return (m_rigid_body == NULL); }
     52    virtual mat4 GetTransform();
     53    virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f)));
    5454protected:
    55         virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix);
     55    virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix);
    5656public:
    57         virtual void SetMass(float mass);
    58         virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false);
    59         virtual void InitBodyToGhost();
    60         virtual void AddToSimulation(class Simulation* current_simulation);
    61         virtual void RemoveFromSimulation(class Simulation* current_simulation);
     57    virtual void SetMass(float mass);
     58    virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false);
     59    virtual void InitBodyToGhost();
     60    virtual void AddToSimulation(class Simulation* current_simulation);
     61    virtual void RemoveFromSimulation(class Simulation* current_simulation);
    6262
    6363protected:
    64         virtual void SetLocalInertia(float mass);
    65         virtual void SetShapeTo(btCollisionShape* collision_shape);
     64    virtual void SetLocalInertia(float mass);
     65    virtual void SetShapeTo(btCollisionShape* collision_shape);
    6666
    67         virtual btGhostObject* GetGhostObjectInstance();
     67    virtual btGhostObject* GetGhostObjectInstance();
    6868
    69         btCollisionObject*                                                      m_collision_object;
     69    btCollisionObject*                            m_collision_object;
    7070
    71         btGhostObject*                                                          m_ghost_object;
     71    btGhostObject*                                m_ghost_object;
    7272
    73         btRigidBody*                                                            m_rigid_body;
    74         btVector3                                                                       m_local_inertia;
     73    btRigidBody*                                m_rigid_body;
     74    btVector3                                    m_local_inertia;
    7575
    76         btCollisionShape*                                                       m_collision_shape;
    77         btConvexShape*                                                          m_convex_shape;
    78         btMotionState*                                                          m_motion_state;
     76    btCollisionShape*                            m_collision_shape;
     77    btConvexShape*                                m_convex_shape;
     78    btMotionState*                                m_motion_state;
    7979
    8080#else  // NO PHYSIC IMPLEMENTATION
    8181
    8282public:
    83         EasyPhysic(WorldEntity* NewOwnerEntity) { m_owner_entity = NewOwnerEntity; }
     83    EasyPhysic(WorldEntity* NewOwnerEntity) { m_owner_entity = NewOwnerEntity; }
    8484
    85         virtual void SetShapeToBox(lol::vec3& BoxSize) { }
    86         virtual void SetShapeToSphere(float radius) { }
    87         virtual void SetShapeToCone(float radius, float height) { }
    88         virtual void SetShapeToCylinder(lol::vec3& cyl_size) { }
    89         virtual void SetShapeToCapsule(float radius, float height) { }
     85    virtual void SetShapeToBox(lol::vec3& BoxSize) { }
     86    virtual void SetShapeToSphere(float radius) { }
     87    virtual void SetShapeToCone(float radius, float height) { }
     88    virtual void SetShapeToCylinder(lol::vec3& cyl_size) { }
     89    virtual void SetShapeToCapsule(float radius, float height) { }
    9090
    91         virtual bool CanChangeCollisionChannel() { return true; }
    92         virtual mat4 GetTransform() { return mat4(1.0f); }
    93         virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))) { }
     91    virtual bool CanChangeCollisionChannel() { return true; }
     92    virtual mat4 GetTransform() { return mat4(1.0f); }
     93    virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))) { }
    9494private:
    95         virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) { }
     95    virtual void BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) { }
    9696public:
    97         virtual void SetMass(float mass) { }
    98         virtual void InitBodyToRigid() { }
    99         virtual void InitBodyToGhost() { }
    100         virtual void AddToSimulation(class Simulation* current_simulation) { }
    101         virtual void RemoveFromSimulation(class Simulation* current_simulation) { }
     97    virtual void SetMass(float mass) { }
     98    virtual void InitBodyToRigid() { }
     99    virtual void InitBodyToGhost() { }
     100    virtual void AddToSimulation(class Simulation* current_simulation) { }
     101    virtual void RemoveFromSimulation(class Simulation* current_simulation) { }
    102102
    103         virtual void InitBodyToGhost() { }
     103    virtual void InitBodyToGhost() { }
    104104
    105105#endif // PHYSIC IMPLEMENTATION
    106106
    107107public:
    108         //Sets the collision Group & Mask.
    109         //Mask can change at runtime, not group !
    110         virtual bool SetCollisionChannel(int NewGroup, int NewMask)
    111         {
    112                 if (CanChangeCollisionChannel())
    113                 {
    114                         m_collision_group = (1<<NewGroup);
    115                         m_collision_mask = NewMask;
    116                         return true;
    117                 }
    118                 return false;
    119         }
    120         int GetCollisionGroup() { return m_collision_group; }
    121         int GetCollisionMask()  { return m_collision_mask; }
     108    //Sets the collision Group & Mask.
     109    //Mask can change at runtime, not group !
     110    virtual bool SetCollisionChannel(int NewGroup, int NewMask)
     111    {
     112        if (CanChangeCollisionChannel())
     113        {
     114            m_collision_group = (1<<NewGroup);
     115            m_collision_mask = NewMask;
     116            return true;
     117        }
     118        return false;
     119    }
     120    int GetCollisionGroup() { return m_collision_group; }
     121    int GetCollisionMask()    { return m_collision_mask; }
    122122
    123         //Base/Attachment logic
    124         virtual void AttachTo(EasyPhysic* NewBase, bool NewBaseLockLocation = true, bool NewBaseLockRotation = true)
    125         {
    126                 if (NewBase == this || (NewBase && NewBase->m_base_physic == this))
    127                         return;
     123    //Base/Attachment logic
     124    virtual void AttachTo(EasyPhysic* NewBase, bool NewBaseLockLocation = true, bool NewBaseLockRotation = true)
     125    {
     126        if (NewBase == this || (NewBase && NewBase->m_base_physic == this))
     127            return;
    128128
    129                 if (NewBase)
    130                 {
    131                         bool bAlreadyExists = false;
    132                         for (int i = 0; i < NewBase->m_based_physic_list.Count(); ++i)
    133                                 if (NewBase->m_based_physic_list[i] == this)
    134                                         bAlreadyExists = true;
    135                         if (!bAlreadyExists)
    136                                 NewBase->m_based_physic_list << this;
    137                         m_base_physic = NewBase;
    138                         m_base_lock_location = NewBaseLockLocation;
    139                         m_base_lock_rotation = NewBaseLockRotation;
    140                 }
    141                 else if (m_base_physic)
    142                 {
    143                         for (int i = 0; i < m_base_physic->m_based_physic_list.Count(); ++i)
    144                                 if (m_base_physic->m_based_physic_list[i] == this)
    145                                         m_base_physic->m_based_physic_list.Remove(i--);
    146                         m_base_physic = NULL;
    147                 }
    148         }
     129        if (NewBase)
     130        {
     131            bool bAlreadyExists = false;
     132            for (int i = 0; i < NewBase->m_based_physic_list.Count(); ++i)
     133                if (NewBase->m_based_physic_list[i] == this)
     134                    bAlreadyExists = true;
     135            if (!bAlreadyExists)
     136                NewBase->m_based_physic_list << this;
     137            m_base_physic = NewBase;
     138            m_base_lock_location = NewBaseLockLocation;
     139            m_base_lock_rotation = NewBaseLockRotation;
     140        }
     141        else if (m_base_physic)
     142        {
     143            for (int i = 0; i < m_base_physic->m_based_physic_list.Count(); ++i)
     144                if (m_base_physic->m_based_physic_list[i] == this)
     145                    m_base_physic->m_based_physic_list.Remove(i--);
     146            m_base_physic = NULL;
     147        }
     148    }
    149149
    150150protected:
    151         lol::mat4                                                                       m_local_to_world;
    152         float                                                                           m_mass;
    153         int                                                                                     m_collision_group;
    154         int                                                                                     m_collision_mask;
    155         WorldEntity*                                                            m_owner_entity;
    156         Simulation*                                                                     m_owner_simulation;
     151    lol::mat4                                    m_local_to_world;
     152    float                                        m_mass;
     153    int                                            m_collision_group;
     154    int                                            m_collision_mask;
     155    WorldEntity*                                m_owner_entity;
     156    Simulation*                                    m_owner_simulation;
    157157
    158         //Base/Attachment logic
    159         Array<EasyPhysic*>                                                      m_based_physic_list;    //List of objects based on this : this object moves, its based object MoveStep with it.
    160         EasyPhysic*                                                                     m_base_physic;                  //Base for this object : The base moves, the object moves with it.
    161         bool                                                                            m_base_lock_location;   //when this is TRUE, location moves with rotation change.
    162         bool                                                                            m_base_lock_rotation;   //when this is TRUE, rotation moves with rotation change.
     158    //Base/Attachment logic
     159    Array<EasyPhysic*>                            m_based_physic_list;    //List of objects based on this : this object moves, its based object MoveStep with it.
     160    EasyPhysic*                                    m_base_physic;            //Base for this object : The base moves, the object moves with it.
     161    bool                                        m_base_lock_location;    //when this is TRUE, location moves with rotation change.
     162    bool                                        m_base_lock_rotation;    //when this is TRUE, rotation moves with rotation change.
    163163
    164         //Touch logic
    165         Array<EasyPhysic*>                                                      m_touching_physic;              //Maintained by ghost objects
     164    //Touch logic
     165    Array<EasyPhysic*>                            m_touching_physic;        //Maintained by ghost objects
    166166};
    167167
  • trunk/test/Physics/Include/LolBtPhysicsIntegration.h

    r1785 r1888  
    2020namespace lol
    2121{
    22         //Override Gamegroups names for Physic-useage
    23         //"_ENT_" means that this is a group for Entities that use EasyPhysic primitives.
    24         //"_EZP_" means that this is a group for EasyPhysic primitives.
    25 #define GAMEGROUP_ENT_INPUT                     GAMEGROUP_BEFORE
    26 #define GAMEGROUP_ENT_PLATFORM          GAMEGROUP_DEFAULT
    27 #define GAMEGROUP_ENT_MAIN                      GAMEGROUP_AFTER
    28 #define GAMEGROUP_EZP_CHAR_CTRLR        GAMEGROUP_AFTER_0
    29 #define GAMEGROUP_SIMULATION            GAMEGROUP_AFTER_1
     22    //Override Gamegroups names for Physic-useage
     23    //"_ENT_" means that this is a group for Entities that use EasyPhysic primitives.
     24    //"_EZP_" means that this is a group for EasyPhysic primitives.
     25#define GAMEGROUP_ENT_INPUT            GAMEGROUP_BEFORE
     26#define GAMEGROUP_ENT_PLATFORM        GAMEGROUP_DEFAULT
     27#define GAMEGROUP_ENT_MAIN            GAMEGROUP_AFTER
     28#define GAMEGROUP_EZP_CHAR_CTRLR    GAMEGROUP_AFTER_0
     29#define GAMEGROUP_SIMULATION        GAMEGROUP_AFTER_1
    3030
    3131#ifdef HAVE_PHYS_USE_BULLET
    3232
    33 #define LOL2BT_UNIT                             1.0f
    34 #define BT2LOL_UNIT                             1.0f
     33#define LOL2BT_UNIT                1.0f
     34#define BT2LOL_UNIT                1.0f
    3535
    36 #define LOL2BT_SIZE                             0.5f
    37 #define BT2LOL_SIZE                             2.0f
     36#define LOL2BT_SIZE                0.5f
     37#define BT2LOL_SIZE                2.0f
    3838
    39 #define LOL2BT_VEC3(ELEMENT)    btVector3((ELEMENT).x, (ELEMENT).y, (ELEMENT).z)
    40 #define BT2LOL_VEC3(ELEMENT)    (*(lol::vec3*)(&(ELEMENT)))
     39#define LOL2BT_VEC3(ELEMENT)    btVector3((ELEMENT).x, (ELEMENT).y, (ELEMENT).z)
     40#define BT2LOL_VEC3(ELEMENT)    (*(lol::vec3*)(&(ELEMENT)))
    4141
    4242//Same as above with Unit taken into account
    43 #define LOL2BTU_VEC3(ELEMENT)   btVector3((ELEMENT).x * LOL2BT_UNIT, (ELEMENT).y * LOL2BT_UNIT, (ELEMENT).z * LOL2BT_UNIT)
    44 #define BT2LOLU_VEC3(ELEMENT)   (*(lol::vec3*)(&(ELEMENT))) * BT2LOL_UNIT
     43#define LOL2BTU_VEC3(ELEMENT)    btVector3((ELEMENT).x * LOL2BT_UNIT, (ELEMENT).y * LOL2BT_UNIT, (ELEMENT).z * LOL2BT_UNIT)
     44#define BT2LOLU_VEC3(ELEMENT)    (*(lol::vec3*)(&(ELEMENT))) * BT2LOL_UNIT
    4545
    46 #define LOL2BT_QUAT(ELEMENT)    btQuaternion((ELEMENT).x, (ELEMENT).y, (ELEMENT).z, (ELEMENT).w)
    47 #define BT2LOL_QUAT(ELEMENT)    lol::quat((ELEMENT).getW(), BT2LOL_VEC3((ELEMENT).getAxis())
     46#define LOL2BT_QUAT(ELEMENT)    btQuaternion((ELEMENT).x, (ELEMENT).y, (ELEMENT).z, (ELEMENT).w)
     47#define BT2LOL_QUAT(ELEMENT)    lol::quat((ELEMENT).getW(), BT2LOL_VEC3((ELEMENT).getAxis())
    4848
    4949#endif // HAVE_PHYS_USE_BULLET
  • trunk/test/Physics/Include/LolPhysics.h

    r1819 r1888  
    2727enum eRaycastType
    2828{
    29         ERT_Closest,
    30         ERT_AllHit,
    31         ERT_AnyHit, //Will stop at the first hit. Hit data are supposed to be irrelevant
    32 
    33         ERT_MAX
     29    ERT_Closest,
     30    ERT_AllHit,
     31    ERT_AnyHit, //Will stop at the first hit. Hit data are supposed to be irrelevant
     32
     33    ERT_MAX
    3434};
    3535
    3636struct RayCastResult
    3737{
    38         RayCastResult(int CollisionFilterGroup=1, int CollisionFilterMask=(0xFF))
    39         {
    40                 memset(this, 0, sizeof(RayCastResult));
    41 
    42                 m_collision_filter_group = CollisionFilterGroup;
    43                 m_collision_filter_mask = CollisionFilterMask;
    44         }
    45         void Reset()
    46         {
    47                 m_collider_list.Empty();
    48                 m_hit_normal_list.Empty();
    49                 m_hit_point_list.Empty();
    50                 m_hit_fraction_list.Empty();
    51         }
    52 
    53         Array<EasyPhysic*>              m_collider_list;
    54         Array<vec3>                             m_hit_normal_list;
    55         Array<vec3>                             m_hit_point_list;
    56         Array<float>                    m_hit_fraction_list;
    57 
    58         short int                               m_collision_filter_group;
    59         short int                               m_collision_filter_mask;
    60         unsigned int                    m_flags; //???
     38    RayCastResult(int CollisionFilterGroup=1, int CollisionFilterMask=(0xFF))
     39    {
     40        memset(this, 0, sizeof(RayCastResult));
     41
     42        m_collision_filter_group = CollisionFilterGroup;
     43        m_collision_filter_mask = CollisionFilterMask;
     44    }
     45    void Reset()
     46    {
     47        m_collider_list.Empty();
     48        m_hit_normal_list.Empty();
     49        m_hit_point_list.Empty();
     50        m_hit_fraction_list.Empty();
     51    }
     52
     53    Array<EasyPhysic*>        m_collider_list;
     54    Array<vec3>                m_hit_normal_list;
     55    Array<vec3>                m_hit_point_list;
     56    Array<float>            m_hit_fraction_list;
     57
     58    short int                m_collision_filter_group;
     59    short int                 m_collision_filter_mask;
     60    unsigned int             m_flags; //???
    6161};
    6262
     
    6464{
    6565public:
    66         Simulation() :
    67                 m_broadphase(0),
    68                 m_collision_configuration(0),
    69                 m_dispatcher(0),
    70                 m_solver(0),
    71                 m_dynamics_world(0),
    72                 m_timestep(1.f/60.f)
    73         {
    74                 m_gamegroup = GAMEGROUP_SIMULATION;
    75         }
    76         ~Simulation()
    77         {
    78                 Exit();
    79         }
    80 
    81         char const *GetName() { return "<Simulation>"; }
     66    Simulation() :
     67        m_broadphase(0),
     68        m_collision_configuration(0),
     69        m_dispatcher(0),
     70        m_solver(0),
     71        m_dynamics_world(0),
     72        m_timestep(1.f/60.f)
     73    {
     74        m_gamegroup = GAMEGROUP_SIMULATION;
     75    }
     76    ~Simulation()
     77    {
     78        Exit();
     79    }
     80
     81    char const *GetName() { return "<Simulation>"; }
    8282
    8383#ifdef HAVE_PHYS_USE_BULLET
    8484public:
    85         void Init()
    86         {
    87                 // Build the broadphase
    88                 if (1)
    89                 {
    90                         m_Sweep_broadphase = new btAxisSweep3(LOL2BT_VEC3(m_world_min), LOL2BT_VEC3(m_world_max));
    91                         m_Sweep_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
    92                         m_broadphase = m_Sweep_broadphase;
    93                 }
    94                 else
    95                         m_broadphase = new btDbvtBroadphase();
    96  
    97                 // Set up the collision configuration and dispatcher
    98                 m_collision_configuration = new btDefaultCollisionConfiguration();
    99                 m_dispatcher = new btCollisionDispatcher(m_collision_configuration);
    100  
    101                 // The actual physics solver
    102                 m_solver = new btSequentialImpulseConstraintSolver;
    103  
    104                 // The world.
    105                 m_dynamics_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collision_configuration);
    106         }
    107 
    108         virtual void TickGame(float seconds)
    109         {
    110                 Entity::TickGame(seconds);
    111 
    112                 //step the simulation
    113                 if (m_dynamics_world)
    114                 {
    115                         //the "+1" is to have at least one Timestep and to ensure float to int .5f conversion.
    116                         int steps = (int)(seconds / m_timestep) + 1;
    117                         m_dynamics_world->stepSimulation(seconds, steps, m_timestep);
    118                 }
    119         }
    120 
    121         //Rip-Off of the btKinematicClosestNotMeRayResultCallback
    122         class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
    123         {
    124         public:
    125                 ClosestNotMeRayResultCallback(btCollisionObject* Me, const btVector3& rayFromWorld, const btVector3& rayToWorld) :
    126                   btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld)
    127                 {
    128                         m_me = Me;
    129                 }
    130 
    131                 virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
    132                 {
    133                         if (rayResult.m_collisionObject == m_me)
    134                                 return 1.0;
    135 
    136                         return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
    137                 }
    138         protected:
    139                 btCollisionObject* m_me;
    140         };
    141 
    142         //Will stop at the first hit. Hit data are supposed to be irrelevant
    143         class AnyHitRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
    144         {
    145         public:
    146                 AnyHitRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) :
    147                   btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld)
    148                 {
    149                 }
    150 
    151                 virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
    152                 {
    153                         return .0f;
    154                 }
    155         };
    156 
    157         //Returns true when hitting something. If SourceCaster is set, it will be ignored by Raycast.
    158         bool RayHits(RayCastResult& HitResult, eRaycastType RaycastType, const vec3& RayFrom, const vec3& RayTo, EasyPhysic* SourceCaster=NULL)
    159         {
    160                 bool bResult = false;
    161 
    162                 btCollisionWorld::RayResultCallback* BtRayResult = NULL;
    163                 btCollisionWorld::ClosestRayResultCallback* BtRayResult_Closest;
    164                 btCollisionWorld::AllHitsRayResultCallback* BtRayResult_AllHits;
    165 
    166                 switch (RaycastType)
    167                 {
    168                         case ERT_Closest:
    169                         {
    170                                 if (SourceCaster)
    171                                         BtRayResult_Closest = new ClosestNotMeRayResultCallback(SourceCaster->m_collision_object, LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
    172                                 else
    173                                         BtRayResult_Closest = new btCollisionWorld::ClosestRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
    174                                 BtRayResult = BtRayResult_Closest;
    175                                 break;
    176                         }
    177                         case ERT_AllHit:
    178                         {
    179                                 BtRayResult_AllHits = new btCollisionWorld::AllHitsRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
    180                                 BtRayResult = BtRayResult_AllHits;
    181                                 break;
    182                         }
    183                         case ERT_AnyHit:
    184                         {
    185                                 BtRayResult_Closest = new AnyHitRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
    186                                 BtRayResult = BtRayResult_Closest;
    187                                 break;
    188                         }
    189                 }
    190 
    191                 m_dynamics_world->rayTest(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo), *BtRayResult);
    192                 if (BtRayResult->hasHit())
    193                 {
    194                         bResult = true;
    195 
    196                         switch (RaycastType)
    197                         {
    198                                 case ERT_Closest:
    199                                 {
    200                                         HitResult.m_collider_list               << (EasyPhysic*)BtRayResult_Closest->m_collisionObject->getUserPointer();
    201                                         HitResult.m_hit_normal_list             << BT2LOLU_VEC3(BtRayResult_Closest->m_hitNormalWorld);
    202                                         HitResult.m_hit_point_list              << BT2LOLU_VEC3(BtRayResult_Closest->m_hitPointWorld);
    203                                         HitResult.m_hit_fraction_list   << BtRayResult_Closest->m_closestHitFraction;
    204                                         break;
    205                                 }
    206                                 case ERT_AllHit:
    207                                 {
    208                                         for (int i = 0; i < BtRayResult_AllHits->m_collisionObjects.size(); i++)
    209                                         {
    210                                                 HitResult.m_collider_list               << (EasyPhysic*)BtRayResult_AllHits->m_collisionObjects[i]->getUserPointer();
    211                                                 HitResult.m_hit_normal_list             << BT2LOLU_VEC3(BtRayResult_AllHits->m_hitNormalWorld[i]);
    212                                                 HitResult.m_hit_point_list              << BT2LOLU_VEC3(BtRayResult_AllHits->m_hitPointWorld[i]);
    213                                                 HitResult.m_hit_fraction_list   << BtRayResult_AllHits->m_hitFractions[i];
    214                                         }
    215                                         break;
    216                                 }
    217                         }
    218                 }
    219 
    220                 delete BtRayResult;
    221 
    222                 return bResult;
    223         }
    224 
    225 
    226         void Exit()
    227         {
    228                 delete m_dynamics_world;
    229                 delete m_solver;
    230                 delete m_dispatcher;
    231                 delete m_collision_configuration;
    232                 delete m_broadphase;
    233         }
    234 
    235         btDiscreteDynamicsWorld* GetWorld()
    236         {
    237                 return m_dynamics_world;
    238         }
     85    void Init()
     86    {
     87        // Build the broadphase
     88        if (1)
     89        {
     90            m_Sweep_broadphase = new btAxisSweep3(LOL2BT_VEC3(m_world_min), LOL2BT_VEC3(m_world_max));
     91            m_Sweep_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
     92            m_broadphase = m_Sweep_broadphase;
     93        }
     94        else
     95            m_broadphase = new btDbvtBroadphase();
     96
     97        // Set up the collision configuration and dispatcher
     98        m_collision_configuration = new btDefaultCollisionConfiguration();
     99        m_dispatcher = new btCollisionDispatcher(m_collision_configuration);
     100
     101        // The actual physics solver
     102        m_solver = new btSequentialImpulseConstraintSolver;
     103
     104        // The world.
     105        m_dynamics_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collision_configuration);
     106    }
     107
     108    virtual void TickGame(float seconds)
     109    {
     110        Entity::TickGame(seconds);
     111
     112        //step the simulation
     113        if (m_dynamics_world)
     114        {
     115            //the "+1" is to have at least one Timestep and to ensure float to int .5f conversion.
     116            int steps = (int)(seconds / m_timestep) + 1;
     117            m_dynamics_world->stepSimulation(seconds, steps, m_timestep);
     118        }
     119    }
     120
     121    //Rip-Off of the btKinematicClosestNotMeRayResultCallback
     122    class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
     123    {
     124    public:
     125        ClosestNotMeRayResultCallback(btCollisionObject* Me, const btVector3& rayFromWorld, const btVector3& rayToWorld) :
     126          btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld)
     127        {
     128            m_me = Me;
     129        }
     130
     131        virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
     132        {
     133            if (rayResult.m_collisionObject == m_me)
     134                return 1.0;
     135
     136            return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
     137        }
     138    protected:
     139        btCollisionObject* m_me;
     140    };
     141
     142    //Will stop at the first hit. Hit data are supposed to be irrelevant
     143    class AnyHitRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
     144    {
     145    public:
     146        AnyHitRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) :
     147          btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld)
     148        {
     149        }
     150
     151        virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
     152        {
     153            return .0f;
     154        }
     155    };
     156
     157    //Returns true when hitting something. If SourceCaster is set, it will be ignored by Raycast.
     158    bool RayHits(RayCastResult& HitResult, eRaycastType RaycastType, const vec3& RayFrom, const vec3& RayTo, EasyPhysic* SourceCaster=NULL)
     159    {
     160        bool bResult = false;
     161
     162        btCollisionWorld::RayResultCallback* BtRayResult = NULL;
     163        btCollisionWorld::ClosestRayResultCallback* BtRayResult_Closest;
     164        btCollisionWorld::AllHitsRayResultCallback* BtRayResult_AllHits;
     165
     166        switch (RaycastType)
     167        {
     168            case ERT_Closest:
     169            {
     170                if (SourceCaster)
     171                    BtRayResult_Closest = new ClosestNotMeRayResultCallback(SourceCaster->m_collision_object, LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
     172                else
     173                    BtRayResult_Closest = new btCollisionWorld::ClosestRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
     174                BtRayResult = BtRayResult_Closest;
     175                break;
     176            }
     177            case ERT_AllHit:
     178            {
     179                BtRayResult_AllHits = new btCollisionWorld::AllHitsRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
     180                BtRayResult = BtRayResult_AllHits;
     181                break;
     182            }
     183            case ERT_AnyHit:
     184            {
     185                BtRayResult_Closest = new AnyHitRayResultCallback(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo));
     186                BtRayResult = BtRayResult_Closest;
     187                break;
     188            }
     189        }
     190
     191        m_dynamics_world->rayTest(LOL2BTU_VEC3(RayFrom), LOL2BTU_VEC3(RayTo), *BtRayResult);
     192        if (BtRayResult->hasHit())
     193        {
     194            bResult = true;
     195
     196            switch (RaycastType)
     197            {
     198                case ERT_Closest:
     199                {
     200                    HitResult.m_collider_list        << (EasyPhysic*)BtRayResult_Closest->m_collisionObject->getUserPointer();
     201                    HitResult.m_hit_normal_list        << BT2LOLU_VEC3(BtRayResult_Closest->m_hitNormalWorld);
     202                    HitResult.m_hit_point_list        << BT2LOLU_VEC3(BtRayResult_Closest->m_hitPointWorld);
     203                    HitResult.m_hit_fraction_list    << BtRayResult_Closest->m_closestHitFraction;
     204                    break;
     205                }
     206                case ERT_AllHit:
     207                {
     208                    for (int i = 0; i < BtRayResult_AllHits->m_collisionObjects.size(); i++)
     209                    {
     210                        HitResult.m_collider_list        << (EasyPhysic*)BtRayResult_AllHits->m_collisionObjects[i]->getUserPointer();
     211                        HitResult.m_hit_normal_list        << BT2LOLU_VEC3(BtRayResult_AllHits->m_hitNormalWorld[i]);
     212                        HitResult.m_hit_point_list        << BT2LOLU_VEC3(BtRayResult_AllHits->m_hitPointWorld[i]);
     213                        HitResult.m_hit_fraction_list    << BtRayResult_AllHits->m_hitFractions[i];
     214                    }
     215                    break;
     216                }
     217            }
     218        }
     219
     220        delete BtRayResult;
     221
     222        return bResult;
     223    }
     224
     225
     226    void Exit()
     227    {
     228        delete m_dynamics_world;
     229        delete m_solver;
     230        delete m_dispatcher;
     231        delete m_collision_configuration;
     232        delete m_broadphase;
     233    }
     234
     235    btDiscreteDynamicsWorld* GetWorld()
     236    {
     237        return m_dynamics_world;
     238    }
    239239
    240240private:
    241         void CustomSetContinuousDetection(bool ShouldUseCCD)
    242         {
    243                 if (m_dynamics_world)
    244                         m_dynamics_world->getDispatchInfo().m_useContinuous = ShouldUseCCD;
    245         }
    246 
    247         void CustomSetGravity(vec3 &NewGravity)
    248         {
    249                 if (m_dynamics_world)
    250                         m_dynamics_world->setGravity(LOL2BT_VEC3(NewGravity * LOL2BT_UNIT));
    251         }
    252 
    253         void CustomSetWorldLimit(vec3 const &NewWorldMin, vec3 const &NewWorldMax)
    254         {
    255         }
    256 
    257         void CustomSetTimestep(float NewTimestep) { }
    258 
    259         //broadphase
    260         btBroadphaseInterface*                                  m_broadphase;
    261         btAxisSweep3*                                                   m_Sweep_broadphase;
    262         // Set up the collision configuration and dispatc
    263         btDefaultCollisionConfiguration*                m_collision_configuration;
    264         btCollisionDispatcher*                                  m_dispatcher;
    265         // The actual physics solver
    266         btSequentialImpulseConstraintSolver*    m_solver;
    267         // The world.
    268         btDiscreteDynamicsWorld*                                m_dynamics_world;
     241    void CustomSetContinuousDetection(bool ShouldUseCCD)
     242    {
     243        if (m_dynamics_world)
     244            m_dynamics_world->getDispatchInfo().m_useContinuous = ShouldUseCCD;
     245    }
     246
     247    void CustomSetGravity(vec3 &NewGravity)
     248    {
     249        if (m_dynamics_world)
     250            m_dynamics_world->setGravity(LOL2BT_VEC3(NewGravity * LOL2BT_UNIT));
     251    }
     252
     253    void CustomSetWorldLimit(vec3 const &NewWorldMin, vec3 const &NewWorldMax)
     254    {
     255    }
     256
     257    void CustomSetTimestep(float NewTimestep) { }
     258
     259    //broadphase
     260    btBroadphaseInterface*                    m_broadphase;
     261    btAxisSweep3*                            m_Sweep_broadphase;
     262    // Set up the collision configuration and dispatc
     263    btDefaultCollisionConfiguration*        m_collision_configuration;
     264    btCollisionDispatcher*                    m_dispatcher;
     265    // The actual physics solver
     266    btSequentialImpulseConstraintSolver*    m_solver;
     267    // The world.
     268    btDiscreteDynamicsWorld*                m_dynamics_world;
    269269
    270270#else  // NO PHYSIC IMPLEMENTATION
    271271
    272272public:
    273         void Init() { }
    274         void TickGame(float seconds) { }
    275         bool RayHits(RayCastResult& HitResult, eRaycastType RaycastType, const vec3& RayFrom, const vec3& RayTo, EasyPhysic* SourceCaster=NULL) { return false; }
    276         void Exit() { }
     273    void Init() { }
     274    void TickGame(float seconds) { }
     275    bool RayHits(RayCastResult& HitResult, eRaycastType RaycastType, const vec3& RayFrom, const vec3& RayTo, EasyPhysic* SourceCaster=NULL) { return false; }
     276    void Exit() { }
    277277private:
    278         void CustomSetContinuousDetection(bool ShouldUseCCD) { }
    279         void CustomSetGravity(vec3 &NewGravity) { }
    280         void CustomSetWorldLimit(vec3 &NewWorldMin, vec3 &NewWorldMax) { }
    281         void CustomSetTimestep(float NewTimestep) { }
     278    void CustomSetContinuousDetection(bool ShouldUseCCD) { }
     279    void CustomSetGravity(vec3 &NewGravity) { }
     280    void CustomSetWorldLimit(vec3 &NewWorldMin, vec3 &NewWorldMax) { }
     281    void CustomSetTimestep(float NewTimestep) { }
    282282
    283283#endif // PHYSIC IMPLEMENTATION
    284284
    285285public:
    286         //Main logic :
    287         //The Set*() functions do the all-lib-independent data storage.
    288         //And then it calls the CustomSet*() which are the specialized versions.
    289 
    290         //Sets the continuous collision detection flag.
    291         void SetContinuousDetection(bool ShouldUseCCD)
    292         {
    293                 m_using_CCD = ShouldUseCCD;
    294                 CustomSetContinuousDetection(ShouldUseCCD);
    295         }
    296 
    297         //Sets the simulation gravity.
    298         void SetGravity(vec3 &NewGravity)
    299         {
    300                 m_gravity = NewGravity;
    301                 CustomSetGravity(NewGravity);
    302         }
    303 
    304         //Sets the simulation gravity.
    305         void SetWorldLimit(vec3 const &NewWorldMin, vec3 const &NewWorldMax)
    306         {
    307                 m_world_min = NewWorldMin;
    308                 m_world_max = NewWorldMax;
    309                 CustomSetWorldLimit(NewWorldMin, NewWorldMax);
    310         }
    311 
    312         //Sets the simulation fixed timestep.
    313         void SetTimestep(float NewTimestep)
    314         {
    315                 if (NewTimestep > .0f)
    316                 {
    317                         m_timestep = NewTimestep;
    318                         CustomSetTimestep(NewTimestep);
    319                 }
    320         }
     286    //Main logic :
     287    //The Set*() functions do the all-lib-independent data storage.
     288    //And then it calls the CustomSet*() which are the specialized versions.
     289
     290    //Sets the continuous collision detection flag.
     291    void SetContinuousDetection(bool ShouldUseCCD)
     292    {
     293        m_using_CCD = ShouldUseCCD;
     294        CustomSetContinuousDetection(ShouldUseCCD);
     295    }
     296
     297    //Sets the simulation gravity.
     298    void SetGravity(vec3 &NewGravity)
     299    {
     300        m_gravity = NewGravity;
     301        CustomSetGravity(NewGravity);
     302    }
     303
     304    //Sets the simulation gravity.
     305    void SetWorldLimit(vec3 const &NewWorldMin, vec3 const &NewWorldMax)
     306    {
     307        m_world_min = NewWorldMin;
     308        m_world_max = NewWorldMax;
     309        CustomSetWorldLimit(NewWorldMin, NewWorldMax);
     310    }
     311
     312    //Sets the simulation fixed timestep.
     313    void SetTimestep(float NewTimestep)
     314    {
     315        if (NewTimestep > .0f)
     316        {
     317            m_timestep = NewTimestep;
     318            CustomSetTimestep(NewTimestep);
     319        }
     320    }
    321321
    322322private:
    323323
    324         friend class EasyPhysic;
    325         friend class EasyCharacterController;
    326         friend class EasyConstraint;
    327 
    328         enum eEasyPhysicType
    329         {
    330                 EEPT_Dynamic,
    331                 EEPT_Static,
    332                 EEPT_Ghost,
    333                 EEPT_CollisionObject,
    334                 EEPT_CharacterController,
    335 
    336                 EEPT_MAX
    337         };
    338 
    339         //m_owner_simulation
    340         //Adds the given EasyPhysic to the correct list.
    341         void ObjectRegistration(bool AddObject, EasyPhysic* NewEP, eEasyPhysicType CurType)
    342         {
    343                 Array<EasyPhysic*>* SearchList = NULL;
    344                 switch(CurType)
    345                 {
    346                         case EEPT_Dynamic:
    347                         {
    348                                 SearchList = &m_dynamic_list;
    349                                 break;
    350                         }
    351                         case EEPT_Static:
    352                         {
    353                                 SearchList = &m_static_list;
    354                                 break;
    355                         }
    356                         case EEPT_Ghost:
    357                         {
    358                                 SearchList = &m_ghost_list;
    359                                 break;
    360                         }
    361                         case EEPT_CollisionObject:
    362                         {
    363                                 SearchList = &m_collision_object_list;
    364                                 break;
    365                         }
    366                         case EEPT_CharacterController:
    367                         {
    368                                 SearchList = &m_character_controller_list;
    369                                 break;
    370                         }
    371                 }
    372 
    373                 if (AddObject)
    374                 {
    375                         NewEP->m_owner_simulation = this;
    376                         (*SearchList) << NewEP;
    377                 }
    378                 else
    379                 {
    380                         NewEP->m_owner_simulation = NULL;
    381                         for (int i = 0; i < SearchList->Count(); ++i)
    382                         {
    383                                 if ((*SearchList)[i] == NewEP)
    384                                 {
    385                                         SearchList->Remove(i--);
    386                                         break;
    387                                 }
    388                         }
    389                 }
    390         }
    391         void ObjectRegistration(bool AddObject, EasyConstraint* NewEC)
    392         {
    393                 Array<EasyConstraint*>* SearchList = NULL;
    394                 SearchList = &m_constraint_list;
    395 
    396                 if (AddObject)
    397                 {
    398                         NewEC->m_owner_simulation = this;
    399                         (*SearchList) << NewEC;
    400                 }
    401                 else
    402                 {
    403                         NewEC->m_owner_simulation = NULL;
    404                         for (int i = 0; i < SearchList->Count(); ++i)
    405                         {
    406                                 if ((*SearchList)[i] == NewEC)
    407                                 {
    408                                         SearchList->Remove(i--);
    409                                         break;
    410                                 }
    411                         }
    412                 }
    413         }
    414 
    415         //Easy Physics body List
    416         Array<EasyPhysic*>                                              m_dynamic_list;
    417         Array<EasyPhysic*>                                              m_static_list;
    418         Array<EasyPhysic*>                                              m_ghost_list;
    419         Array<EasyPhysic*>                                              m_collision_object_list;
    420         Array<EasyPhysic*>                                              m_character_controller_list;
    421         Array<EasyConstraint*>                                  m_constraint_list;
    422 
    423         //Easy Physics data storage
    424         float                                                                   m_timestep;
    425         bool                                                                    m_using_CCD;
    426         vec3                                                                    m_gravity;
    427         vec3                                                                    m_world_min;
    428         vec3                                                                    m_world_max;
     324    friend class EasyPhysic;
     325    friend class EasyCharacterController;
     326    friend class EasyConstraint;
     327
     328    enum eEasyPhysicType
     329    {
     330        EEPT_Dynamic,
     331        EEPT_Static,
     332        EEPT_Ghost,
     333        EEPT_CollisionObject,
     334        EEPT_CharacterController,
     335
     336        EEPT_MAX
     337    };
     338
     339    //m_owner_simulation
     340    //Adds the given EasyPhysic to the correct list.
     341    void ObjectRegistration(bool AddObject, EasyPhysic* NewEP, eEasyPhysicType CurType)
     342    {
     343        Array<EasyPhysic*>* SearchList = NULL;
     344        switch(CurType)
     345        {
     346            case EEPT_Dynamic:
     347            {
     348                SearchList = &m_dynamic_list;
     349                break;
     350            }
     351            case EEPT_Static:
     352            {
     353                SearchList = &m_static_list;
     354                break;
     355            }
     356            case EEPT_Ghost:
     357            {
     358                SearchList = &m_ghost_list;
     359                break;
     360            }
     361            case EEPT_CollisionObject:
     362            {
     363                SearchList = &m_collision_object_list;
     364                break;
     365            }
     366            case EEPT_CharacterController:
     367            {
     368                SearchList = &m_character_controller_list;
     369                break;
     370            }
     371        }
     372
     373        if (AddObject)
     374        {
     375            NewEP->m_owner_simulation = this;
     376            (*SearchList) << NewEP;
     377        }
     378        else
     379        {
     380            NewEP->m_owner_simulation = NULL;
     381            for (int i = 0; i < SearchList->Count(); ++i)
     382            {
     383                if ((*SearchList)[i] == NewEP)
     384                {
     385                    SearchList->Remove(i--);
     386                    break;
     387                }
     388            }
     389        }
     390    }
     391    void ObjectRegistration(bool AddObject, EasyConstraint* NewEC)
     392    {
     393        Array<EasyConstraint*>* SearchList = NULL;
     394        SearchList = &m_constraint_list;
     395
     396        if (AddObject)
     397        {
     398            NewEC->m_owner_simulation = this;
     399            (*SearchList) << NewEC;
     400        }
     401        else
     402        {
     403            NewEC->m_owner_simulation = NULL;
     404            for (int i = 0; i < SearchList->Count(); ++i)
     405            {
     406                if ((*SearchList)[i] == NewEC)
     407                {
     408                    SearchList->Remove(i--);
     409                    break;
     410                }
     411            }
     412        }
     413    }
     414
     415    //Easy Physics body List
     416    Array<EasyPhysic*>                        m_dynamic_list;
     417    Array<EasyPhysic*>                        m_static_list;
     418    Array<EasyPhysic*>                        m_ghost_list;
     419    Array<EasyPhysic*>                        m_collision_object_list;
     420    Array<EasyPhysic*>                        m_character_controller_list;
     421    Array<EasyConstraint*>                    m_constraint_list;
     422
     423    //Easy Physics data storage
     424    float                                    m_timestep;
     425    bool                                    m_using_CCD;
     426    vec3                                    m_gravity;
     427    vec3                                    m_world_min;
     428    vec3                                    m_world_max;
    429429};
    430430
  • trunk/test/Physics/Src/BulletCharacterController.cpp

    r1870 r1888  
    4646bool BulletKinematicCharacterController::RecoverFromPenetration(btCollisionWorld* CollisionWorld)
    4747{
    48         bool HasPenetration = false;
    49 
    50         //Retrieve all pair with us colliding.
    51         CollisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghost_object->getOverlappingPairCache(), CollisionWorld->getDispatchInfo(), CollisionWorld->getDispatcher());
    52         m_current_position = BT2LOLU_VEC3(m_ghost_object->getWorldTransform().getOrigin());
    53        
    54         float MaxPen = .0f;
    55         for (int i = 0; i < m_ghost_object->getOverlappingPairCache()->getNumOverlappingPairs(); i++)
    56         {
    57                 m_manifold_array.resize(0);
    58 
    59                 //this is the equivalent of the "Touch algorithm". Maybe refactor ?
    60                 btBroadphasePair* CollisionPair = &m_ghost_object->getOverlappingPairCache()->getOverlappingPairArray()[i];
    61                 if (CollisionPair->m_algorithm)
    62                         CollisionPair->m_algorithm->getAllContactManifolds(m_manifold_array);
    63                
    64                 for (int j = 0; j < m_manifold_array.size(); ++j)
    65                 {
    66                         btPersistentManifold* CurMfold = m_manifold_array[j];
    67                         //Normal direction differs if we're Body0
    68                         float DirSign = CurMfold->getBody0() == m_ghost_object ? -1.f : 1.f;
    69 
    70                         for (int k = 0; k < CurMfold->getNumContacts(); k++)
    71                         {
    72                                 const btManifoldPoint& MfPoint = CurMfold->getContactPoint(k);
    73                                 float Dist = MfPoint.getDistance();
    74                                 if (Dist < .0f)
    75                                 {
    76                                         if (Dist < MaxPen)
    77                                         {
    78                                                 MaxPen = Dist;
    79                                                 m_touching_normal = BT2LOL_VEC3(MfPoint.m_normalWorldOnB) * DirSign;
    80                                         }
    81                                         m_current_position += BT2LOL_VEC3(MfPoint.m_normalWorldOnB) * DirSign * Dist * .2f;
    82                                         HasPenetration = true;
    83                                 }
    84                         }
    85                 }
    86         }
    87 
    88         btTransform GObjMx = m_ghost_object->getWorldTransform();
    89         GObjMx.setOrigin(LOL2BTU_VEC3(m_current_position));
    90         m_ghost_object->setWorldTransform(GObjMx);
    91 
    92         return HasPenetration;
     48    bool HasPenetration = false;
     49
     50    //Retrieve all pair with us colliding.
     51    CollisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghost_object->getOverlappingPairCache(), CollisionWorld->getDispatchInfo(), CollisionWorld->getDispatcher());
     52    m_current_position = BT2LOLU_VEC3(m_ghost_object->getWorldTransform().getOrigin());
     53
     54    float MaxPen = .0f;
     55    for (int i = 0; i < m_ghost_object->getOverlappingPairCache()->getNumOverlappingPairs(); i++)
     56    {
     57        m_manifold_array.resize(0);
     58
     59        //this is the equivalent of the "Touch algorithm". Maybe refactor ?
     60        btBroadphasePair* CollisionPair = &m_ghost_object->getOverlappingPairCache()->getOverlappingPairArray()[i];
     61        if (CollisionPair->m_algorithm)
     62            CollisionPair->m_algorithm->getAllContactManifolds(m_manifold_array);
     63
     64        for (int j = 0; j < m_manifold_array.size(); ++j)
     65        {
     66            btPersistentManifold* CurMfold = m_manifold_array[j];
     67            //Normal direction differs if we're Body0
     68            float DirSign = CurMfold->getBody0() == m_ghost_object ? -1.f : 1.f;
     69
     70            for (int k = 0; k < CurMfold->getNumContacts(); k++)
     71            {
     72                const btManifoldPoint& MfPoint = CurMfold->getContactPoint(k);
     73                float Dist = MfPoint.getDistance();
     74                if (Dist < .0f)
     75                {
     76                    if (Dist < MaxPen)
     77                    {
     78                        MaxPen = Dist;
     79                        m_touching_normal = BT2LOL_VEC3(MfPoint.m_normalWorldOnB) * DirSign;
     80                    }
     81                    m_current_position += BT2LOL_VEC3(MfPoint.m_normalWorldOnB) * DirSign * Dist * .2f;
     82                    HasPenetration = true;
     83                }
     84            }
     85        }
     86    }
     87
     88    btTransform GObjMx = m_ghost_object->getWorldTransform();
     89    GObjMx.setOrigin(LOL2BTU_VEC3(m_current_position));
     90    m_ghost_object->setWorldTransform(GObjMx);
     91
     92    return HasPenetration;
    9393}
    9494
     
    9696void BulletKinematicCharacterController::UpdateTargetOnHit(const vec3& HitNormal, float TangentMag, float NormalMag)
    9797{
    98         vec3 Movedir = m_target_position - m_current_position;
    99         float MoveLength = (float)length(Movedir);
    100 
    101         if (MoveLength > SIMD_EPSILON)
    102         {
    103                 Movedir = normalize(Movedir);
    104 
    105                 vec3 ReflectDir = normalize(GetReflectedDir(Movedir, HitNormal));
    106                 vec3 ParallelDir = ProjectDirOnNorm(ReflectDir, HitNormal);
    107                 vec3 PerpindicularDir = ProjectDirOnNormPerpindicular(ReflectDir, HitNormal);
    108 
    109                 m_target_position = m_current_position;
    110 
    111                 if (NormalMag != .0f)
    112                         m_target_position += PerpindicularDir * NormalMag * MoveLength;
    113         }
     98    vec3 Movedir = m_target_position - m_current_position;
     99    float MoveLength = (float)length(Movedir);
     100
     101    if (MoveLength > SIMD_EPSILON)
     102    {
     103        Movedir = normalize(Movedir);
     104
     105        vec3 ReflectDir = normalize(GetReflectedDir(Movedir, HitNormal));
     106        vec3 ParallelDir = ProjectDirOnNorm(ReflectDir, HitNormal);
     107        vec3 PerpindicularDir = ProjectDirOnNormPerpindicular(ReflectDir, HitNormal);
     108
     109        m_target_position = m_current_position;
     110
     111        if (NormalMag != .0f)
     112            m_target_position += PerpindicularDir * NormalMag * MoveLength;
     113    }
    114114}
    115115
     
    117117void BulletKinematicCharacterController::DoMove(btCollisionWorld* CollisionWorld, const vec3& MoveStep, float DeltaTime)
    118118{
    119         // phase 2: forward and strafe
    120         m_target_position = m_current_position + MoveStep;
    121         btTransform SweepStart, SweepEnd;
    122         SweepStart.setIdentity();
    123         SweepEnd.setIdentity();
    124 
    125         float Fraction = 1.f;
    126         float SqDist = .0f;
    127 
    128         if (m_touching_contact && dot(m_normalized_direction, m_touching_normal) > .0f)
    129                 UpdateTargetOnHit(m_touching_normal);
    130 
    131         //Let's loop on movement, until Movement fraction if below 0.01, which means we've reached our destination.
    132         //Or until we'tried 10 times.
    133         int MaxMoveLoop = 10;
    134         while (Fraction > .01f && MaxMoveLoop-- > 0)
    135         {
    136                 SweepStart.setOrigin(LOL2BTU_VEC3(m_current_position));
    137                 SweepEnd.setOrigin(LOL2BTU_VEC3(m_target_position));
    138                 vec3 SweepDirNeg(m_current_position - m_target_position);
    139 
    140                 ClosestNotMeConvexResultCallback SweepCallback(m_ghost_object, SweepDirNeg, .0f);
    141                 SweepCallback.m_collisionFilterGroup = GetGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
    142                 SweepCallback.m_collisionFilterMask = GetGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
    143 
    144                 //The sweep test is done with an added margin, so we use it and then discard it
    145                 float SavedMargin = m_convex_shape->getMargin();
    146                 m_convex_shape->setMargin(SavedMargin + m_added_margin); //Apply Added Margin
    147                 if (m_do_gobject_sweep_test)
    148                         m_ghost_object->convexSweepTest (m_convex_shape, SweepStart, SweepEnd, SweepCallback, CollisionWorld->getDispatchInfo().m_allowedCcdPenetration);
    149                 else
    150                         CollisionWorld->convexSweepTest (m_convex_shape, SweepStart, SweepEnd, SweepCallback, CollisionWorld->getDispatchInfo().m_allowedCcdPenetration);
    151                 m_convex_shape->setMargin(SavedMargin); //Restore saved margin
    152 
    153                 Fraction -= SweepCallback.m_closestHitFraction;
    154 
    155                 if (SweepCallback.hasHit())
    156                 {       
    157                         //We moved only a Fraction
    158                         float HitDist = (float)length(BT2LOLU_VEC3(SweepCallback.m_hitPointWorld) - m_current_position);
    159 
    160                         UpdateTargetOnHit(BT2LOL_VEC3(SweepCallback.m_hitNormalWorld));
    161                         vec3 NewDir = m_target_position - m_current_position;
    162                         SqDist = sqlength(NewDir);
    163                         if (SqDist > SIMD_EPSILON)
    164                         {
    165                                 NewDir = normalize(NewDir);
    166                                 //See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners."
    167                                 if (dot(NewDir, m_normalized_direction) <= .0f)
    168                                         break;
    169                         }
    170                         else
    171                                 break;
    172                 }
    173                 else //We moved whole way
    174                         m_current_position = m_target_position;
    175         }
     119    // phase 2: forward and strafe
     120    m_target_position = m_current_position + MoveStep;
     121    btTransform SweepStart, SweepEnd;
     122    SweepStart.setIdentity();
     123    SweepEnd.setIdentity();
     124
     125    float Fraction = 1.f;
     126    float SqDist = .0f;
     127
     128    if (m_touching_contact && dot(m_normalized_direction, m_touching_normal) > .0f)
     129        UpdateTargetOnHit(m_touching_normal);
     130
     131    //Let's loop on movement, until Movement fraction if below 0.01, which means we've reached our destination.
     132    //Or until we'tried 10 times.
     133    int MaxMoveLoop = 10;
     134    while (Fraction > .01f && MaxMoveLoop-- > 0)
     135    {
     136        SweepStart.setOrigin(LOL2BTU_VEC3(m_current_position));
     137        SweepEnd.setOrigin(LOL2BTU_VEC3(m_target_position));
     138        vec3 SweepDirNeg(m_current_position - m_target_position);
     139
     140        ClosestNotMeConvexResultCallback SweepCallback(m_ghost_object, SweepDirNeg, .0f);
     141        SweepCallback.m_collisionFilterGroup = GetGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
     142        SweepCallback.m_collisionFilterMask = GetGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
     143
     144        //The sweep test is done with an added margin, so we use it and then discard it
     145        float SavedMargin = m_convex_shape->getMargin();
     146        m_convex_shape->setMargin(SavedMargin + m_added_margin); //Apply Added Margin
     147        if (m_do_gobject_sweep_test)
     148            m_ghost_object->convexSweepTest (m_convex_shape, SweepStart, SweepEnd, SweepCallback, CollisionWorld->getDispatchInfo().m_allowedCcdPenetration);
     149        else
     150            CollisionWorld->convexSweepTest (m_convex_shape, SweepStart, SweepEnd, SweepCallback, CollisionWorld->getDispatchInfo().m_allowedCcdPenetration);
     151        m_convex_shape->setMargin(SavedMargin); //Restore saved margin
     152
     153        Fraction -= SweepCallback.m_closestHitFraction;
     154
     155        if (SweepCallback.hasHit())
     156        {
     157            //We moved only a Fraction
     158            float HitDist = (float)length(BT2LOLU_VEC3(SweepCallback.m_hitPointWorld) - m_current_position);
     159
     160            UpdateTargetOnHit(BT2LOL_VEC3(SweepCallback.m_hitNormalWorld));
     161            vec3 NewDir = m_target_position - m_current_position;
     162            SqDist = sqlength(NewDir);
     163            if (SqDist > SIMD_EPSILON)
     164            {
     165                NewDir = normalize(NewDir);
     166                //See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners."
     167                if (dot(NewDir, m_normalized_direction) <= .0f)
     168                    break;
     169            }
     170            else
     171                break;
     172        }
     173        else //We moved whole way
     174            m_current_position = m_target_position;
     175    }
    176176}
    177177
     
    179179void BulletKinematicCharacterController::PreStep(btCollisionWorld* CollisionWorld)
    180180{
    181         int MaxPenetrationLoop = 0;
    182         m_touching_contact = false;
    183 
    184         while (RecoverFromPenetration(CollisionWorld))
    185         {
    186                 MaxPenetrationLoop++;
    187                 m_touching_contact = true;
    188                 if (MaxPenetrationLoop > 4)
    189                         break;
    190         }
    191 
    192         m_current_position = BT2LOLU_VEC3(m_ghost_object->getWorldTransform().getOrigin());
    193         m_target_position = m_current_position;
     181    int MaxPenetrationLoop = 0;
     182    m_touching_contact = false;
     183
     184    while (RecoverFromPenetration(CollisionWorld))
     185    {
     186        MaxPenetrationLoop++;
     187        m_touching_contact = true;
     188        if (MaxPenetrationLoop > 4)
     189            break;
     190    }
     191
     192    m_current_position = BT2LOLU_VEC3(m_ghost_object->getWorldTransform().getOrigin());
     193    m_target_position = m_current_position;
    194194}
    195195
     
    198198void BulletKinematicCharacterController::PlayerStep(btCollisionWorld* CollisionWorld, float DeltaTime)
    199199{
    200         // quick check...
    201         if (!m_use_walk_direction && m_velocity_time_interval <= .0f)
    202                 return;         // no motion
    203 
    204         // Update fall velocity.
    205         //m_velocity -= m_gravity * DeltaTime;
    206 
    207         btTransform NewTransform;
    208         NewTransform = m_ghost_object->getWorldTransform();
    209 
    210         vec3 MoveStep(.0f);
    211         if (m_use_walk_direction)
    212                 MoveStep = m_walk_direction;
    213         else
    214         {
    215                 //Still have some time left for moving!
    216                 float dtMoving = (DeltaTime < m_velocity_time_interval) ? DeltaTime : m_velocity_time_interval;
    217                 m_velocity_time_interval -= DeltaTime;
    218 
    219                 // how far will we MoveStep while we are moving?
    220                 MoveStep = m_walk_direction * dtMoving;
    221         }
    222 
    223         //Okay, step !
    224         DoMove(CollisionWorld, MoveStep, DeltaTime);
    225 
    226         //Movement finished, update World transform
    227         NewTransform.setOrigin(LOL2BTU_VEC3(m_current_position));
    228         m_ghost_object->setWorldTransform(NewTransform);
     200    // quick check...
     201    if (!m_use_walk_direction && m_velocity_time_interval <= .0f)
     202        return;        // no motion
     203
     204    // Update fall velocity.
     205    //m_velocity -= m_gravity * DeltaTime;
     206
     207    btTransform NewTransform;
     208    NewTransform = m_ghost_object->getWorldTransform();
     209
     210    vec3 MoveStep(.0f);
     211    if (m_use_walk_direction)
     212        MoveStep = m_walk_direction;
     213    else
     214    {
     215        //Still have some time left for moving!
     216        float dtMoving = (DeltaTime < m_velocity_time_interval) ? DeltaTime : m_velocity_time_interval;
     217        m_velocity_time_interval -= DeltaTime;
     218
     219        // how far will we MoveStep while we are moving?
     220        MoveStep = m_walk_direction * dtMoving;
     221    }
     222
     223    //Okay, step !
     224    DoMove(CollisionWorld, MoveStep, DeltaTime);
     225
     226    //Movement finished, update World transform
     227    NewTransform.setOrigin(LOL2BTU_VEC3(m_current_position));
     228    m_ghost_object->setWorldTransform(NewTransform);
    229229}
    230230
     
    232232void BulletKinematicCharacterController::Jump()
    233233{
    234         if (!CanJump())
    235                 return;
    236 
    237         m_vertical_velocity = m_jump_speed;
    238         m_was_jumping = true;
     234    if (!CanJump())
     235        return;
     236
     237    m_vertical_velocity = m_jump_speed;
     238    m_was_jumping = true;
    239239}
    240240
     
    242242#endif // USE_LOL_CTRLR_CHARAC
    243243
    244         } /* namespace phys */
     244    } /* namespace phys */
    245245
    246246} /* namespace lol */
  • trunk/test/Physics/Src/EasyCharacterController.cpp

    r1870 r1888  
    3939btGhostObject* EasyCharacterController::GetGhostObjectInstance()
    4040{
    41         return new btPairCachingGhostObject();
     41    return new btPairCachingGhostObject();
    4242}
    4343
     
    4545void EasyCharacterController::InitBodyToGhost()
    4646{
    47         EasyPhysic::InitBodyToGhost();
     47    EasyPhysic::InitBodyToGhost();
    4848
    49         m_pair_caching_object = (btPairCachingGhostObject*)m_ghost_object;
    50         m_ghost_object->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT | m_ghost_object->getCollisionFlags());
     49    m_pair_caching_object = (btPairCachingGhostObject*)m_ghost_object;
     50    m_ghost_object->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT | m_ghost_object->getCollisionFlags());
    5151}
    5252
     
    5454void EasyCharacterController::AddToSimulation(class Simulation* current_simulation)
    5555{
    56         EasyPhysic::AddToSimulation(current_simulation);
     56    EasyPhysic::AddToSimulation(current_simulation);
    5757
    58         btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
    59         if (dynamics_world)
    60         {
    61                 if (m_character)
    62                         delete m_character;
     58    btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
     59    if (dynamics_world)
     60    {
     61        if (m_character)
     62            delete m_character;
    6363
    64                 //m_character = new btKinematicCharacterController(m_pair_caching_object, m_convex_shape, m_step_height, m_up_axis);
    65                 m_character = new BulletKinematicCharacterController(m_pair_caching_object, m_convex_shape, m_step_height, m_up_axis);
     64        //m_character = new btKinematicCharacterController(m_pair_caching_object, m_convex_shape, m_step_height, m_up_axis);
     65        m_character = new BulletKinematicCharacterController(m_pair_caching_object, m_convex_shape, m_step_height, m_up_axis);
    6666
    67                 //Deactivate Character controller basic behaviour.
    68                 //m_character->setGravity(.0f);
    69                 //m_character->setFallSpeed(.0f);
     67        //Deactivate Character controller basic behaviour.
     68        //m_character->setGravity(.0f);
     69        //m_character->setFallSpeed(.0f);
    7070
    71                 dynamics_world->addAction(m_character);
    72                 current_simulation->ObjectRegistration(true, this, Simulation::EEPT_CharacterController);
    73                 Ticker::Ref(this);
    74         }
     71        dynamics_world->addAction(m_character);
     72        current_simulation->ObjectRegistration(true, this, Simulation::EEPT_CharacterController);
     73        Ticker::Ref(this);
     74    }
    7575}
    7676
     
    7878void EasyCharacterController::RemoveFromSimulation(class Simulation* current_simulation)
    7979{
    80         EasyPhysic::RemoveFromSimulation(current_simulation);
     80    EasyPhysic::RemoveFromSimulation(current_simulation);
    8181
    82         btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
    83         if (dynamics_world)
    84         {
    85                 if (m_character)
    86                 {
    87                         dynamics_world->removeAction(m_character);
    88                         current_simulation->ObjectRegistration(false, this, Simulation::EEPT_CharacterController);
    89                         Ticker::Unref(this);
    90                 }
    91         }
     82    btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
     83    if (dynamics_world)
     84    {
     85        if (m_character)
     86        {
     87            dynamics_world->removeAction(m_character);
     88            current_simulation->ObjectRegistration(false, this, Simulation::EEPT_CharacterController);
     89            Ticker::Unref(this);
     90        }
     91    }
    9292}
    9393
    9494void EasyCharacterController::Jump()
    9595{
    96         m_character->Jump();
     96    m_character->Jump();
    9797}
    9898
     
    100100void EasyCharacterController::SetMovementForFrame(vec3 const &MoveQuantity)
    101101{
    102         m_frame_cached_movement = MoveQuantity;
     102    m_frame_cached_movement = MoveQuantity;
    103103}
    104104
     
    108108void EasyCharacterController::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation)
    109109{
    110         if (m_base_is_updating)
    111         {
    112                 m_base_cached_movement = base_location - m_local_to_world.v3.xyz;
    113                 m_local_to_world = lol::mat4::translate(m_local_to_world.v3.xyz) * lol::mat4(base_rotation);
    114                 if (m_ghost_object)
    115                         m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * m_local_to_world.v3.xyz)));
    116         }
    117         else
    118                 EasyPhysic::SetTransform(base_location, base_rotation);
     110    if (m_base_is_updating)
     111    {
     112        m_base_cached_movement = base_location - m_local_to_world.v3.xyz;
     113        m_local_to_world = lol::mat4::translate(m_local_to_world.v3.xyz) * lol::mat4(base_rotation);
     114        if (m_ghost_object)
     115            m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * m_local_to_world.v3.xyz)));
     116    }
     117    else
     118        EasyPhysic::SetTransform(base_location, base_rotation);
    119119}
    120120
     
    122122void EasyCharacterController::BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix)
    123123{
    124         m_base_is_updating = true;
    125         EasyPhysic::BaseTransformChanged(PreviousMatrix, NewMatrix);
    126         m_base_is_updating = false;
     124    m_base_is_updating = true;
     125    EasyPhysic::BaseTransformChanged(PreviousMatrix, NewMatrix);
     126    m_base_is_updating = false;
    127127}
    128128
     
    130130char const *EasyCharacterController::GetName()
    131131{
    132         return "<EasyCharacterController>";
     132    return "<EasyCharacterController>";
    133133}
    134134
     
    136136void EasyCharacterController::TickGame(float seconds)
    137137{
    138         Entity::TickGame(seconds);
     138    Entity::TickGame(seconds);
    139139
    140         //Send final velocity in Bullet
    141         {
    142                 int IterationsNb = (int)(seconds / m_owner_simulation->m_timestep);
    143                 float NewSeconds = IterationsNb * m_owner_simulation->m_timestep;
    144                 m_character->SetVelocityForTimeInterval((m_base_cached_movement + m_frame_cached_movement) / NewSeconds, NewSeconds);
    145                 m_base_cached_movement = vec3(.0f);
    146         }
     140    //Send final velocity in Bullet
     141    {
     142        int IterationsNb = (int)(seconds / m_owner_simulation->m_timestep);
     143        float NewSeconds = IterationsNb * m_owner_simulation->m_timestep;
     144        m_character->SetVelocityForTimeInterval((m_base_cached_movement + m_frame_cached_movement) / NewSeconds, NewSeconds);
     145        m_base_cached_movement = vec3(.0f);
     146    }
    147147}
    148148
  • trunk/test/Physics/Src/EasyConstraint.cpp

    r1782 r1888  
    2222void EasyConstraint::AddToSimulation(class Simulation* current_simulation)
    2323{
    24         btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
    25         if (dynamics_world && m_typed_constraint)
    26         {
    27                 dynamics_world->addConstraint(m_typed_constraint, m_disable_a2b_collision);
    28                 current_simulation->ObjectRegistration(true, this);
    29         }
     24    btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
     25    if (dynamics_world && m_typed_constraint)
     26    {
     27        dynamics_world->addConstraint(m_typed_constraint, m_disable_a2b_collision);
     28        current_simulation->ObjectRegistration(true, this);
     29    }
    3030}
    3131
    3232void EasyConstraint::RemoveFromSimulation(class Simulation* current_simulation)
    3333{
    34         btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
    35         if (dynamics_world && m_typed_constraint)
    36         {
    37                 dynamics_world->removeConstraint(m_typed_constraint);
    38                 current_simulation->ObjectRegistration(false, this);
    39         }
     34    btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
     35    if (dynamics_world && m_typed_constraint)
     36    {
     37        dynamics_world->removeConstraint(m_typed_constraint);
     38        current_simulation->ObjectRegistration(false, this);
     39    }
    4040}
    4141
  • trunk/test/Physics/Src/EasyPhysics.cpp

    r1782 r1888  
    3030//--
    3131
    32 EasyPhysic::EasyPhysic(WorldEntity* NewOwnerEntity) : 
    33         m_collision_object(NULL),
    34         m_ghost_object(NULL),
    35         m_rigid_body(NULL),
    36         m_local_inertia(btVector3(.0f, .0f, .0f)),
    37         m_collision_shape(NULL),
    38         m_convex_shape(NULL),
    39         m_motion_state(NULL),
    40         m_mass(.0f),
    41         m_collision_group(1),
    42         m_collision_mask(1),
    43         m_owner_entity(NewOwnerEntity),
    44         m_owner_simulation(NULL),
    45         m_base_physic(NULL)
     32EasyPhysic::EasyPhysic(WorldEntity* NewOwnerEntity) :
     33    m_collision_object(NULL),
     34    m_ghost_object(NULL),
     35    m_rigid_body(NULL),
     36    m_local_inertia(btVector3(.0f, .0f, .0f)),
     37    m_collision_shape(NULL),
     38    m_convex_shape(NULL),
     39    m_motion_state(NULL),
     40    m_mass(.0f),
     41    m_collision_group(1),
     42    m_collision_mask(1),
     43    m_owner_entity(NewOwnerEntity),
     44    m_owner_simulation(NULL),
     45    m_base_physic(NULL)
    4646{
    4747}
     
    4949EasyPhysic::~EasyPhysic()
    5050{
    51         m_rigid_body = NULL;
    52         delete m_collision_object;
    53         delete m_collision_shape;
    54         delete m_motion_state;
     51    m_rigid_body = NULL;
     52    delete m_collision_object;
     53    delete m_collision_shape;
     54    delete m_motion_state;
    5555}
    5656
     
    6161void EasyPhysic::SetShapeTo(btCollisionShape* collision_shape)
    6262{
    63         bool bReinitToRigidBody = false;
    64         if (m_rigid_body)
    65         {
    66                 bReinitToRigidBody = true;
    67                 delete m_rigid_body;
    68         }
    69         if (m_collision_shape)
    70                 delete m_collision_shape;
    71 
    72         m_collision_shape = collision_shape;
    73 
    74         if (bReinitToRigidBody)
    75                 InitBodyToRigid();
     63    bool bReinitToRigidBody = false;
     64    if (m_rigid_body)
     65    {
     66        bReinitToRigidBody = true;
     67        delete m_rigid_body;
     68    }
     69    if (m_collision_shape)
     70        delete m_collision_shape;
     71
     72    m_collision_shape = collision_shape;
     73
     74    if (bReinitToRigidBody)
     75        InitBodyToRigid();
    7676}
    7777
     
    7979void EasyPhysic::SetShapeToBox(lol::vec3& box_size)
    8080{
    81         vec3 new_box_size = box_size * LOL2BT_UNIT * LOL2BT_SIZE;
    82         m_convex_shape = new btBoxShape(LOL2BT_VEC3(new_box_size));
    83         SetShapeTo(m_convex_shape);
     81    vec3 new_box_size = box_size * LOL2BT_UNIT * LOL2BT_SIZE;
     82    m_convex_shape = new btBoxShape(LOL2BT_VEC3(new_box_size));
     83    SetShapeTo(m_convex_shape);
    8484}
    8585
    8686void EasyPhysic::SetShapeToSphere(float radius)
    8787{
    88         m_convex_shape = new btSphereShape(radius * LOL2BT_UNIT * LOL2BT_SIZE);
    89         SetShapeTo(m_convex_shape);
     88    m_convex_shape = new btSphereShape(radius * LOL2BT_UNIT * LOL2BT_SIZE);
     89    SetShapeTo(m_convex_shape);
    9090}
    9191
    9292void EasyPhysic::SetShapeToCone(float radius, float height)
    9393{
    94         m_convex_shape = new btConeShape(       radius * LOL2BT_UNIT,
    95                                                                                 height * LOL2BT_UNIT);
    96         SetShapeTo(m_convex_shape);
     94    m_convex_shape = new btConeShape(    radius * LOL2BT_UNIT,
     95                                        height * LOL2BT_UNIT);
     96    SetShapeTo(m_convex_shape);
    9797}
    9898
    9999void EasyPhysic::SetShapeToCylinder(lol::vec3& cyl_size)
    100100{
    101         vec3 new_cyl_size = cyl_size * LOL2BT_UNIT;
    102         new_cyl_size.y *= LOL2BT_SIZE;
    103         m_convex_shape = new btCylinderShape(LOL2BT_VEC3(new_cyl_size));
    104         SetShapeTo(m_convex_shape);
     101    vec3 new_cyl_size = cyl_size * LOL2BT_UNIT;
     102    new_cyl_size.y *= LOL2BT_SIZE;
     103    m_convex_shape = new btCylinderShape(LOL2BT_VEC3(new_cyl_size));
     104    SetShapeTo(m_convex_shape);
    105105}
    106106
    107107void EasyPhysic::SetShapeToCapsule(float radius, float height)
    108108{
    109         m_convex_shape = new btCapsuleShape(radius * LOL2BT_UNIT * LOL2BT_SIZE,
    110                                                                                 height * LOL2BT_UNIT * LOL2BT_SIZE);
    111         SetShapeTo(m_convex_shape);
     109    m_convex_shape = new btCapsuleShape(radius * LOL2BT_UNIT * LOL2BT_SIZE,
     110                                        height * LOL2BT_UNIT * LOL2BT_SIZE);
     111    SetShapeTo(m_convex_shape);
    112112}
    113113
     
    119119mat4 EasyPhysic::GetTransform()
    120120{
    121         m_local_to_world = lol::mat4(1.0f);
    122         if (m_rigid_body && m_motion_state)
    123         {
    124                 btTransform CurTransform;
    125                 m_motion_state->getWorldTransform(CurTransform);
    126                 CurTransform.getOpenGLMatrix(&m_local_to_world[0][0]);
    127         }
    128         else if (m_collision_object)
    129                 m_collision_object->getWorldTransform().getOpenGLMatrix(&m_local_to_world[0][0]);
    130         return m_local_to_world;
     121    m_local_to_world = lol::mat4(1.0f);
     122    if (m_rigid_body && m_motion_state)
     123    {
     124        btTransform CurTransform;
     125        m_motion_state->getWorldTransform(CurTransform);
     126        CurTransform.getOpenGLMatrix(&m_local_to_world[0][0]);
     127    }
     128    else if (m_collision_object)
     129        m_collision_object->getWorldTransform().getOpenGLMatrix(&m_local_to_world[0][0]);
     130    return m_local_to_world;
    131131}
    132132
     
    134134void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation)
    135135{
    136         lol::mat4 PreviousMatrix = m_local_to_world;
    137         m_local_to_world = lol::mat4::translate(base_location) * lol::mat4(base_rotation);
    138 
    139         if (m_ghost_object)
    140                 m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location)));
    141         else
    142         {
    143                 if (m_motion_state)
    144                         m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location)));
    145                 else
    146                         m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location)));
    147         }
    148 
    149         for (int i = 0; i < m_based_physic_list.Count(); i++)
    150         {
    151                 if (m_based_physic_list[i])
    152                         m_based_physic_list[i]->BaseTransformChanged(PreviousMatrix, m_local_to_world);
    153                 else
    154                         m_based_physic_list.Remove(i--);
    155         }
     136    lol::mat4 PreviousMatrix = m_local_to_world;
     137    m_local_to_world = lol::mat4::translate(base_location) * lol::mat4(base_rotation);
     138
     139    if (m_ghost_object)
     140        m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location)));
     141    else
     142    {
     143        if (m_motion_state)
     144            m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location)));
     145        else
     146            m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * base_location)));
     147    }
     148
     149    for (int i = 0; i < m_based_physic_list.Count(); i++)
     150    {
     151        if (m_based_physic_list[i])
     152            m_based_physic_list[i]->BaseTransformChanged(PreviousMatrix, m_local_to_world);
     153        else
     154            m_based_physic_list.Remove(i--);
     155    }
    156156}
    157157
     
    159159void EasyPhysic::BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix)
    160160{
    161         mat4 PreviousMatrixLoc = ((m_base_lock_location)?(PreviousMatrix):(lol::mat4::translate(PreviousMatrix.v3.xyz)));
    162         mat4 PreviousMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(PreviousMatrix))):(lol::mat4(1.f)));
    163         mat4 NewMatrixLoc = ((m_base_lock_location)?(NewMatrix):(lol::mat4::translate(NewMatrix.v3.xyz)));
    164         mat4 NewMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(NewMatrix))):(lol::mat4(1.f)));
    165        
    166         if (m_ghost_object || (m_rigid_body->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT))
    167         {
    168                 mat4 ThisMatrixLoc = NewMatrixLoc * inverse(PreviousMatrixLoc) * lol::mat4::translate(m_local_to_world.v3.xyz);
    169                 mat4 ThisMatrixRot = NewMatrixRot * inverse(PreviousMatrixRot) * lol::mat4(lol::quat(m_local_to_world));
    170                 SetTransform(ThisMatrixLoc.v3.xyz, lol::mat4(lol::quat(ThisMatrixRot)));
    171         }
     161    mat4 PreviousMatrixLoc = ((m_base_lock_location)?(PreviousMatrix):(lol::mat4::translate(PreviousMatrix.v3.xyz)));
     162    mat4 PreviousMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(PreviousMatrix))):(lol::mat4(1.f)));
     163    mat4 NewMatrixLoc = ((m_base_lock_location)?(NewMatrix):(lol::mat4::translate(NewMatrix.v3.xyz)));
     164    mat4 NewMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(NewMatrix))):(lol::mat4(1.f)));
     165
     166    if (m_ghost_object || (m_rigid_body->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT))
     167    {
     168        mat4 ThisMatrixLoc = NewMatrixLoc * inverse(PreviousMatrixLoc) * lol::mat4::translate(m_local_to_world.v3.xyz);
     169        mat4 ThisMatrixRot = NewMatrixRot * inverse(PreviousMatrixRot) * lol::mat4(lol::quat(m_local_to_world));
     170        SetTransform(ThisMatrixLoc.v3.xyz, lol::mat4(lol::quat(ThisMatrixRot)));
     171    }
    172172}
    173173
     
    178178void EasyPhysic::SetMass(float mass)
    179179{
    180         m_mass = mass;
    181 
    182         if (m_rigid_body)
    183         {
    184                 SetLocalInertia(m_mass);
    185                 m_rigid_body->setMassProps(mass, m_local_inertia);
    186         }
     180    m_mass = mass;
     181
     182    if (m_rigid_body)
     183    {
     184        SetLocalInertia(m_mass);
     185        m_rigid_body->setMassProps(mass, m_local_inertia);
     186    }
    187187}
    188188
     
    194194void EasyPhysic::InitBodyToRigid(bool SetToKinematic)
    195195{
    196         if (m_collision_object)
    197                 delete m_collision_object;
    198 
    199         if (!m_motion_state)
    200                 SetTransform(vec3(.0f));
    201 
    202         btRigidBody::btRigidBodyConstructionInfo NewInfos(m_mass, m_motion_state, m_collision_shape, m_local_inertia);
    203         m_rigid_body = new btRigidBody(NewInfos);
    204         m_collision_object = m_rigid_body;
    205         m_collision_object->setUserPointer(this);
    206 
    207         if (m_mass == .0f)
    208         {
    209                 if (SetToKinematic)
    210                 {
    211                         m_rigid_body->setActivationState(DISABLE_DEACTIVATION);
    212                         m_rigid_body->setCollisionFlags(m_rigid_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
    213                 }
    214         }
    215         else
    216                 SetMass(m_mass);
     196    if (m_collision_object)
     197        delete m_collision_object;
     198
     199    if (!m_motion_state)
     200        SetTransform(vec3(.0f));
     201
     202    btRigidBody::btRigidBodyConstructionInfo NewInfos(m_mass, m_motion_state, m_collision_shape, m_local_inertia);
     203    m_rigid_body = new btRigidBody(NewInfos);
     204    m_collision_object = m_rigid_body;
     205    m_collision_object->setUserPointer(this);
     206
     207    if (m_mass == .0f)
     208    {
     209        if (SetToKinematic)
     210        {
     211            m_rigid_body->setActivationState(DISABLE_DEACTIVATION);
     212            m_rigid_body->setCollisionFlags(m_rigid_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
     213        }
     214    }
     215    else
     216        SetMass(m_mass);
    217217}
    218218
     
    220220btGhostObject* EasyPhysic::GetGhostObjectInstance()
    221221{
    222         return new btGhostObject();
     222    return new btGhostObject();
    223223}
    224224
     
    226226void EasyPhysic::InitBodyToGhost()
    227227{
    228         if (m_collision_object)
    229                 delete m_collision_object;
    230 
    231         m_ghost_object = GetGhostObjectInstance();
    232         m_ghost_object->setCollisionShape(m_collision_shape);
    233         m_collision_object = m_ghost_object;
    234         m_collision_object->setUserPointer(this);
    235 
    236         SetTransform(m_local_to_world.v3.xyz, lol::quat(m_local_to_world));
    237 
    238         m_ghost_object->setCollisionFlags(m_ghost_object->getCollisionFlags());
     228    if (m_collision_object)
     229        delete m_collision_object;
     230
     231    m_ghost_object = GetGhostObjectInstance();
     232    m_ghost_object->setCollisionShape(m_collision_shape);
     233    m_collision_object = m_ghost_object;
     234    m_collision_object->setUserPointer(this);
     235
     236    SetTransform(m_local_to_world.v3.xyz, lol::quat(m_local_to_world));
     237
     238    m_ghost_object->setCollisionFlags(m_ghost_object->getCollisionFlags());
    239239}
    240240
     
    251251
    252252  //       const btBroadphasePair& pair = pairArray[i];
    253   //       
     253  //
    254254  //       //unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache:
    255255  //       btBroadphasePair* collisionPair = dynamicsWorld->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1);
     
    266266  //          for (int p=0;p<manifold->getNumContacts();p++)
    267267  //          {
    268   //            const btManifoldPoint&pt = manifold->getContactPoint(p);
     268  //               const btManifoldPoint&pt = manifold->getContactPoint(p);
    269269  //              if (pt.getDistance()<0.f)
    270                 //{
    271                 //      const btVector3& ptA = pt.getPositionWorldOnA();
    272                 //      const btVector3& ptB = pt.getPositionWorldOnB();
    273                 //      const btVector3& normalOnB = pt.m_normalWorldOnB;
    274                 //      /// work here
    275                 //}
     270        //{
     271        //    const btVector3& ptA = pt.getPositionWorldOnA();
     272        //    const btVector3& ptB = pt.getPositionWorldOnB();
     273        //    const btVector3& normalOnB = pt.m_normalWorldOnB;
     274        //    /// work here
     275        //}
    276276  //          }
    277277  //       }
     
    282282void EasyPhysic::AddToSimulation(class Simulation* current_simulation)
    283283{
    284         btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
    285         if (dynamics_world)
    286         {
    287                 if (m_ghost_object)
    288                 {
    289                         dynamics_world->addCollisionObject(m_ghost_object, m_collision_group, m_collision_mask);
    290                         current_simulation->ObjectRegistration(true, this, Simulation::EEPT_Ghost);
    291                 }
    292                 else if (m_rigid_body)
    293                 {
    294                         dynamics_world->addRigidBody(m_rigid_body, m_collision_group, m_collision_mask);
    295                         if (m_mass != .0f)
    296                                 current_simulation->ObjectRegistration(true, this, Simulation::EEPT_Dynamic);
    297                         else
    298                                 current_simulation->ObjectRegistration(true, this, Simulation::EEPT_Static);
    299                 }
    300                 else
    301                 {
    302                         dynamics_world->addCollisionObject(m_collision_object, m_collision_group, m_collision_mask);
    303                         current_simulation->ObjectRegistration(true, this, Simulation::EEPT_CollisionObject);
    304                 }
    305         }
     284    btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
     285    if (dynamics_world)
     286    {
     287        if (m_ghost_object)
     288        {
     289            dynamics_world->addCollisionObject(m_ghost_object, m_collision_group, m_collision_mask);
     290            current_simulation->ObjectRegistration(true, this, Simulation::EEPT_Ghost);
     291        }
     292        else if (m_rigid_body)
     293        {
     294            dynamics_world->addRigidBody(m_rigid_body, m_collision_group, m_collision_mask);
     295            if (m_mass != .0f)
     296                current_simulation->ObjectRegistration(true, this, Simulation::EEPT_Dynamic);
     297            else
     298                current_simulation->ObjectRegistration(true, this, Simulation::EEPT_Static);
     299        }
     300        else
     301        {
     302            dynamics_world->addCollisionObject(m_collision_object, m_collision_group, m_collision_mask);
     303            current_simulation->ObjectRegistration(true, this, Simulation::EEPT_CollisionObject);
     304        }
     305    }
    306306}
    307307
     
    309309void EasyPhysic::RemoveFromSimulation(class Simulation* current_simulation)
    310310{
    311         btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
    312         if (dynamics_world)
    313         {
    314                 if (m_rigid_body)
    315                 {
    316                         dynamics_world->removeRigidBody(m_rigid_body);
    317                         if (m_mass != .0f)
    318                                 current_simulation->ObjectRegistration(false, this, Simulation::EEPT_Dynamic);
    319                         else
    320                                 current_simulation->ObjectRegistration(false, this, Simulation::EEPT_Static);
    321                 }
    322                 else
    323                 {
    324                         dynamics_world->removeCollisionObject(m_collision_object);
    325                         if (m_ghost_object)
    326                                 current_simulation->ObjectRegistration(false, this, Simulation::EEPT_Ghost);
    327                         current_simulation->ObjectRegistration(false, this, Simulation::EEPT_CollisionObject);
    328                 }
    329         }
     311    btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
     312    if (dynamics_world)
     313    {
     314        if (m_rigid_body)
     315        {
     316            dynamics_world->removeRigidBody(m_rigid_body);
     317            if (m_mass != .0f)
     318                current_simulation->ObjectRegistration(false, this, Simulation::EEPT_Dynamic);
     319            else
     320                current_simulation->ObjectRegistration(false, this, Simulation::EEPT_Static);
     321        }
     322        else
     323        {
     324            dynamics_world->removeCollisionObject(m_collision_object);
     325            if (m_ghost_object)
     326                current_simulation->ObjectRegistration(false, this, Simulation::EEPT_Ghost);
     327            current_simulation->ObjectRegistration(false, this, Simulation::EEPT_CollisionObject);
     328        }
     329    }
    330330}
    331331
     
    333333void EasyPhysic::SetLocalInertia(float mass)
    334334{
    335         if (mass != .0f)
    336                 m_collision_shape->calculateLocalInertia(mass, m_local_inertia);
    337         else
    338                 m_local_inertia = btVector3(.0f, .0f, .0f);
     335    if (mass != .0f)
     336        m_collision_shape->calculateLocalInertia(mass, m_local_inertia);
     337    else
     338        m_local_inertia = btVector3(.0f, .0f, .0f);
    339339}
    340340
Note: See TracChangeset for help on using the changeset viewer.