Changeset 1888


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

fixed 23 files out of 277:

  • fixed 1270 CR characters
  • fixed 56 trailing spaces
  • fixed 5085 tabs
Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/easymesh/easymesh.cpp

    r1879 r1888  
    241241{
    242242    Array<int> Welded;
    243         Welded.Push(-1);
     243    Welded.Push(-1);
    244244    for (int i = m_cursors.Last().m1 + 1; i < m_vert.Count(); i++)
    245         {
    246                 int j, k;
    247                 for (j = m_cursors.Last().m1, k = 0; j < i; j++, k++)
    248                 {
    249                         if(Welded[k] < 0)
    250                         {
    251                                 vec3 diff = m_vert[i].m1 - m_vert[j].m1;
    252                                
    253                                 if(diff.x > 0.1f || diff.x < -0.1f)
    254                                         continue;
    255 
    256                                 if(diff.y > 0.1f || diff.y < -0.1f)
    257                                         continue;
    258 
    259                                 if(diff.z > 0.1f || diff.z < -0.1f)
    260                                         continue;
    261 
    262                                 break;
    263                         }
    264                 }
    265 
    266                 if(j == i)
    267                         Welded.Push(-1);
    268                 else
    269                         Welded.Push(j);
    270         }
    271 
    272         int i, j;
     245    {
     246        int j, k;
     247        for (j = m_cursors.Last().m1, k = 0; j < i; j++, k++)
     248        {
     249            if(Welded[k] < 0)
     250            {
     251                vec3 diff = m_vert[i].m1 - m_vert[j].m1;
     252
     253                if(diff.x > 0.1f || diff.x < -0.1f)
     254                    continue;
     255
     256                if(diff.y > 0.1f || diff.y < -0.1f)
     257                    continue;
     258
     259                if(diff.z > 0.1f || diff.z < -0.1f)
     260                    continue;
     261
     262                break;
     263            }
     264        }
     265
     266        if(j == i)
     267            Welded.Push(-1);
     268        else
     269            Welded.Push(j);
     270    }
     271
     272    int i, j;
    273273    for (i = m_cursors.Last().m1, j = 0; i < m_vert.Count(); i++, j++)
    274         {
    275                 if(Welded[j] == -1)
    276                         m_vert[i].m1 *= 1.0f + RandF(r);
    277                 else
    278                         m_vert[i].m1 = m_vert[Welded[j]].m1;
    279         }
    280 
    281         ComputeNormals(m_cursors.Last().m2, m_indices.Count() - m_cursors.Last().m2);
     274    {
     275        if(Welded[j] == -1)
     276            m_vert[i].m1 *= 1.0f + RandF(r);
     277        else
     278            m_vert[i].m1 = m_vert[Welded[j]].m1;
     279    }
     280
     281    ComputeNormals(m_cursors.Last().m2, m_indices.Count() - m_cursors.Last().m2);
    282282}
    283283
     
    362362
    363363    /* Construct normal */
    364         if (r2 != .0f)
    365                 n = vec3(r2, h * .5f, 0.f);
    366         else
    367                 n = vec3(r1, h * .5f, 0.f);
     364    if (r2 != .0f)
     365        n = vec3(r2, h * .5f, 0.f);
     366    else
     367        n = vec3(r1, h * .5f, 0.f);
    368368    n.y = r1 * (r1 - r2) / h;
    369369    if (!smooth)
     
    851851    for (int i = 0; i < ilen / 3; i++)
    852852    {
    853          
     853
    854854    }
    855855
  • trunk/src/entity.h

    r1785 r1888  
    4646        GAMEGROUP_BEFORE = 0,
    4747        GAMEGROUP_DEFAULT,
    48                 GAMEGROUP_AFTER,
    49                 GAMEGROUP_AFTER_0,
    50                 GAMEGROUP_AFTER_1,
     48        GAMEGROUP_AFTER,
     49        GAMEGROUP_AFTER_0,
     50        GAMEGROUP_AFTER_1,
    5151
    52                 // Must be the last element
     52        // Must be the last element
    5353        GAMEGROUP_END
    5454    }
  • trunk/src/input/input.cpp

    r1815 r1888  
    3232 */
    3333
    34 InputTracker*                   Input::m_input_tracker = NULL;
     34InputTracker*            Input::m_input_tracker = NULL;
    3535
    3636static class InputData
     
    6767int ButtonSetting::GetActionSettingIdx(ACTION_TYPE SearchAction)
    6868{
    69         for (int i = 0; i < m_associated_action_list.Count(); i++)
    70                 if (ACTION_CMP(m_associated_action_list[i].m_action, SearchAction))
    71                         return i;
    72         return -1;
     69    for (int i = 0; i < m_associated_action_list.Count(); i++)
     70        if (ACTION_CMP(m_associated_action_list[i].m_action, SearchAction))
     71            return i;
     72    return -1;
    7373}
    7474
     
    7979InputTracker::InputTracker()
    8080{
    81         m_gamegroup = GAMEGROUP_BEFORE;
    82 
    83         for (int i = 0; i < Key::Last * 2; ++i)
    84                 m_input_status << 0;
    85 
    86         Ticker::Ref(this);
     81    m_gamegroup = GAMEGROUP_BEFORE;
     82
     83    for (int i = 0; i < Key::Last * 2; ++i)
     84        m_input_status << 0;
     85
     86    Ticker::Ref(this);
    8787}
    8888
     
    9090int InputTracker::GetButtonSettingIdx(Key Button)
    9191{
    92         for (int i = 0; i < m_input_assocation_list.Count(); i++)
    93                 if (m_input_assocation_list[i].m_raw_button == Button)
    94                         return i;
    95         return -1;
     92    for (int i = 0; i < m_input_assocation_list.Count(); i++)
     93        if (m_input_assocation_list[i].m_raw_button == Button)
     94            return i;
     95    return -1;
    9696}
    9797
     
    9999int InputTracker::GetCurrentButtonStatus(Key Button)
    100100{
    101         if (Button < m_input_status.Count())
    102                 return m_input_status[Button];
    103         return 0;
     101    if (Button < m_input_status.Count())
     102        return m_input_status[Button];
     103    return 0;
    104104}
    105105
     
    107107int InputTracker::GetPreviousButtonStatus(Key Button)
    108108{
    109         if (Button < m_input_status.Count())
    110                 return m_input_status[(int)Button + (int)Key::Last];
    111         return 0;
     109    if (Button < m_input_status.Count())
     110        return m_input_status[(int)Button + (int)Key::Last];
     111    return 0;
    112112}
    113113
     
    117117#if defined USE_SDL
    118118#if SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION >= 3
    119         Uint8 *keystate = SDL_GetKeyboardState(NULL);
     119    Uint8 *keystate = SDL_GetKeyboardState(NULL);
    120120#else
    121         Uint8 *keystate = SDL_GetKeyState(NULL);
    122 #endif
    123         //SOOOoooo ugly.
    124         for (int i = 0; i < Key::Last; ++i)
    125         {
    126                 m_input_status[i + Key::Last] = m_input_status[i];
    127                 m_input_status[i] = keystate[i];
    128         }
    129 #endif
    130 
    131         for (int i = 0; i < m_input_assocation_list.Count(); i++)
    132         {
    133                 ButtonSetting &CurIT = m_input_assocation_list[i];
    134 
    135                 for (int j = 0; j < CurIT.m_associated_action_list.Count(); j++)
    136                 {
    137                         ActionSetting &CurAS = CurIT.m_associated_action_list[j];
    138 
    139                         if (CurAS.m_buffered_since <= CurAS.m_buffering_time)
    140                                 CurAS.m_buffered_since += seconds;
    141 
    142                         if (GetCurrentButtonStatus(CurIT.m_raw_button) &&
    143                                 CurAS.m_buffering_time >= .0f)
    144                                 CurAS.m_buffered_since = .0f;
    145                 }
    146         }
     121    Uint8 *keystate = SDL_GetKeyState(NULL);
     122#endif
     123    //SOOOoooo ugly.
     124    for (int i = 0; i < Key::Last; ++i)
     125    {
     126        m_input_status[i + Key::Last] = m_input_status[i];
     127        m_input_status[i] = keystate[i];
     128    }
     129#endif
     130
     131    for (int i = 0; i < m_input_assocation_list.Count(); i++)
     132    {
     133        ButtonSetting &CurIT = m_input_assocation_list[i];
     134
     135        for (int j = 0; j < CurIT.m_associated_action_list.Count(); j++)
     136        {
     137            ActionSetting &CurAS = CurIT.m_associated_action_list[j];
     138
     139            if (CurAS.m_buffered_since <= CurAS.m_buffering_time)
     140                CurAS.m_buffered_since += seconds;
     141
     142            if (GetCurrentButtonStatus(CurIT.m_raw_button) &&
     143                CurAS.m_buffering_time >= .0f)
     144                CurAS.m_buffered_since = .0f;
     145        }
     146    }
    147147}
    148148
     
    150150void InputTracker::LinkActionToKey(ACTION_TYPE Action, Key Button)
    151151{
    152         int ITIdx = GetButtonSettingIdx(Button);
    153         if (ITIdx == -1)
    154         {
    155                 ITIdx = m_input_assocation_list.Count();
    156                 m_input_assocation_list << ButtonSetting(Button);
    157         }
    158 
    159         ButtonSetting &CurIT = m_input_assocation_list[ITIdx];
    160 
    161         int ASIdx = CurIT.GetActionSettingIdx(Action);
    162         if (ASIdx == -1)
    163         {
    164                 ASIdx = CurIT.m_associated_action_list.Count();
    165                 CurIT.m_associated_action_list << ActionSetting(Action);
    166         }
     152    int ITIdx = GetButtonSettingIdx(Button);
     153    if (ITIdx == -1)
     154    {
     155        ITIdx = m_input_assocation_list.Count();
     156        m_input_assocation_list << ButtonSetting(Button);
     157    }
     158
     159    ButtonSetting &CurIT = m_input_assocation_list[ITIdx];
     160
     161    int ASIdx = CurIT.GetActionSettingIdx(Action);
     162    if (ASIdx == -1)
     163    {
     164        ASIdx = CurIT.m_associated_action_list.Count();
     165        CurIT.m_associated_action_list << ActionSetting(Action);
     166    }
    167167}
    168168
     
    170170void InputTracker::UnlinkAction(ACTION_TYPE Action)
    171171{
    172         for (int i = 0; i < m_input_assocation_list.Count(); i++)
    173         {
    174                 ButtonSetting &CurIT = m_input_assocation_list[i];
    175                 int ASIdx = CurIT.GetActionSettingIdx(Action);
    176                 if (ASIdx != -1)
    177                         CurIT.m_associated_action_list.Remove(ASIdx);
    178         }
     172    for (int i = 0; i < m_input_assocation_list.Count(); i++)
     173    {
     174        ButtonSetting &CurIT = m_input_assocation_list[i];
     175        int ASIdx = CurIT.GetActionSettingIdx(Action);
     176        if (ASIdx != -1)
     177            CurIT.m_associated_action_list.Remove(ASIdx);
     178    }
    179179}
    180180
     
    182182int InputTracker::GetStatus(ACTION_TYPE Action)
    183183{
    184         for (int i = 0; i < m_input_assocation_list.Count(); i++)
    185         {
    186                 ButtonSetting &CurIT = m_input_assocation_list[i];
    187                 int ASIdx = CurIT.GetActionSettingIdx(Action);
    188                 if (ASIdx != -1)
    189                 {
    190                         ActionSetting &CurAS = CurIT.m_associated_action_list[ASIdx];
    191 
    192                         if (CurAS.m_buffering_time >= .0f && CurAS.m_buffered_since <= CurAS.m_buffering_time)
    193                                 return 1;
    194                         return 0;
    195                 }
    196         }
    197         return 0;
     184    for (int i = 0; i < m_input_assocation_list.Count(); i++)
     185    {
     186        ButtonSetting &CurIT = m_input_assocation_list[i];
     187        int ASIdx = CurIT.GetActionSettingIdx(Action);
     188        if (ASIdx != -1)
     189        {
     190            ActionSetting &CurAS = CurIT.m_associated_action_list[ASIdx];
     191
     192            if (CurAS.m_buffering_time >= .0f && CurAS.m_buffered_since <= CurAS.m_buffering_time)
     193                return 1;
     194            return 0;
     195        }
     196    }
     197    return 0;
    198198}
    199199
     
    201201bool InputTracker::WasReleased(ACTION_TYPE Action)
    202202{
    203         for (int i = 0; i < m_input_assocation_list.Count(); i++)
    204         {
    205                 ButtonSetting &CurIT = m_input_assocation_list[i];
    206                 int ASIdx = CurIT.GetActionSettingIdx(Action);
    207                 if (ASIdx != -1)
    208                 {
    209                        
    210                         if (GetPreviousButtonStatus(CurIT.m_raw_button) &&
    211                                 !GetCurrentButtonStatus(CurIT.m_raw_button))
    212                                 return true;
    213                         return false;
    214                 }
    215         }
    216         return false;
     203    for (int i = 0; i < m_input_assocation_list.Count(); i++)
     204    {
     205        ButtonSetting &CurIT = m_input_assocation_list[i];
     206        int ASIdx = CurIT.GetActionSettingIdx(Action);
     207        if (ASIdx != -1)
     208        {
     209
     210            if (GetPreviousButtonStatus(CurIT.m_raw_button) &&
     211                !GetCurrentButtonStatus(CurIT.m_raw_button))
     212                return true;
     213            return false;
     214        }
     215    }
     216    return false;
    217217}
    218218
     
    220220bool InputTracker::WasPressed(ACTION_TYPE Action)
    221221{
    222         for (int i = 0; i < m_input_assocation_list.Count(); i++)
    223         {
    224                 ButtonSetting &CurIT = m_input_assocation_list[i];
    225                 int ASIdx = CurIT.GetActionSettingIdx(Action);
    226                 if (ASIdx != -1)
    227                 {
    228                         if (!GetPreviousButtonStatus(CurIT.m_raw_button) &&
    229                                 GetCurrentButtonStatus(CurIT.m_raw_button))
    230                                 return true;
    231                         return false;
    232                 }
    233         }
    234         return false;
     222    for (int i = 0; i < m_input_assocation_list.Count(); i++)
     223    {
     224        ButtonSetting &CurIT = m_input_assocation_list[i];
     225        int ASIdx = CurIT.GetActionSettingIdx(Action);
     226        if (ASIdx != -1)
     227        {
     228            if (!GetPreviousButtonStatus(CurIT.m_raw_button) &&
     229                GetCurrentButtonStatus(CurIT.m_raw_button))
     230                return true;
     231            return false;
     232        }
     233    }
     234    return false;
    235235}
    236236
     
    238238int InputTracker::GetStatus(Key Button)
    239239{
    240         return GetCurrentButtonStatus(Button);
     240    return GetCurrentButtonStatus(Button);
    241241}
    242242
     
    244244bool InputTracker::WasReleased(Key Button)
    245245{
    246         if (GetPreviousButtonStatus(Button) &&
    247                 !GetCurrentButtonStatus(Button))
    248                 return true;
    249         return false;
     246    if (GetPreviousButtonStatus(Button) &&
     247        !GetCurrentButtonStatus(Button))
     248        return true;
     249    return false;
    250250}
    251251
     
    253253bool InputTracker::WasPressed(Key Button)
    254254{
    255         if (!GetPreviousButtonStatus(Button) &&
    256                 GetCurrentButtonStatus(Button))
    257                 return true;
    258         return false;
     255    if (!GetPreviousButtonStatus(Button) &&
     256        GetCurrentButtonStatus(Button))
     257        return true;
     258    return false;
    259259}
    260260
     
    317317void Input::LinkActionToKey(ACTION_TYPE Action, struct Key Button)
    318318{
    319         if (CheckInputTrackerInit())
    320                 Input::m_input_tracker->LinkActionToKey(Action, Button);
     319    if (CheckInputTrackerInit())
     320        Input::m_input_tracker->LinkActionToKey(Action, Button);
    321321}
    322322
     
    324324void Input::UnlinkAction(ACTION_TYPE Action)
    325325{
    326         if (CheckInputTrackerInit())
    327                 Input::m_input_tracker->UnlinkAction(Action);
     326    if (CheckInputTrackerInit())
     327        Input::m_input_tracker->UnlinkAction(Action);
    328328}
    329329
     
    331331int Input::GetStatus(ACTION_TYPE Action)
    332332{
    333         if (CheckInputTrackerInit())
    334                 return Input::m_input_tracker->GetStatus(Action);
    335         return 0;
     333    if (CheckInputTrackerInit())
     334        return Input::m_input_tracker->GetStatus(Action);
     335    return 0;
    336336}
    337337
     
    339339bool Input::WasPressed(ACTION_TYPE Action)
    340340{
    341         if (CheckInputTrackerInit())
    342                 return Input::m_input_tracker->WasPressed(Action);
    343         return false;
     341    if (CheckInputTrackerInit())
     342        return Input::m_input_tracker->WasPressed(Action);
     343    return false;
    344344}
    345345
     
    347347bool Input::WasReleased(ACTION_TYPE Action)
    348348{
    349         if (CheckInputTrackerInit())
    350                 return Input::m_input_tracker->WasReleased(Action);
    351         return false;
     349    if (CheckInputTrackerInit())
     350        return Input::m_input_tracker->WasReleased(Action);
     351    return false;
    352352}
    353353
     
    355355int Input::GetStatus(Key Button)
    356356{
    357         if (CheckInputTrackerInit())
    358                 return Input::m_input_tracker->GetStatus(Button);
    359         return 0;
     357    if (CheckInputTrackerInit())
     358        return Input::m_input_tracker->GetStatus(Button);
     359    return 0;
    360360}
    361361
     
    363363bool Input::WasPressed(Key Button)
    364364{
    365         if (CheckInputTrackerInit())
    366                 return Input::m_input_tracker->WasPressed(Button);
    367         return false;
     365    if (CheckInputTrackerInit())
     366        return Input::m_input_tracker->WasPressed(Button);
     367    return false;
    368368}
    369369
     
    371371bool Input::WasReleased(Key Button)
    372372{
    373         if (CheckInputTrackerInit())
    374                 return Input::m_input_tracker->WasReleased(Button);
    375         return false;
     373    if (CheckInputTrackerInit())
     374        return Input::m_input_tracker->WasReleased(Button);
     375    return false;
    376376}
    377377
  • trunk/src/input/input.h

    r1803 r1888  
    410410    static ivec3 GetMouseButtons();
    411411
    412     //BH : Shouldn't use this 
     412    //BH : Shouldn't use this
    413413    static int GetButtonState(int button);
    414414
  • trunk/src/lol/math/math.h

    r1833 r1888  
    6767static inline double lerp(double const &a, double const &b, double const &x)
    6868{
    69         return a + (b - a) * x;
     69    return a + (b - a) * x;
    7070}
    7171static inline float lerp(float const &a, float const &b, float const &x)
    7272{
    73         return a + (b - a) * x;
     73    return a + (b - a) * x;
    7474}
    7575
  • trunk/src/numeric.h

    r1833 r1888  
    5656template <typename T1, typename T2, typename Tf> static inline T1 damp(const T1 &a, const T2 &b, const Tf &x, const Tf &dt)
    5757{
    58         if (dt <= .0f)
    59                 return a;
     58    if (dt <= .0f)
     59        return a;
    6060    return lol::lerp(a, b, dt / (dt + x));
    6161}
  • trunk/src/worldentity.cpp

    r1376 r1888  
    2929    m_rotation = quat(1);
    3030    m_velocity = vec3(0);
    31         m_rotation_velocity = vec3(0);
     31    m_rotation_velocity = vec3(0);
    3232    m_bbox[0] = m_bbox[1] = vec3(0);
    3333
  • trunk/test/BtPhysTest.cpp

    r1844 r1888  
    5050int gNumObjects = 64;
    5151
    52 #define USE_WALL                1
    53 #define USE_PLATFORM    1
    54 #define USE_ROPE                0
    55 #define USE_BODIES              1
    56 #define USE_ROTATION    0
    57 #define USE_CHARACTER   1
    58 #define USE_STAIRS              1
    59 
    60 #define IPT_MOVE_FORWARD                "Move_Forward"
    61 #define IPT_MOVE_BACKWARD               "Move_Backward"
    62 #define IPT_MOVE_LEFT                   "Move_Left"
    63 #define IPT_MOVE_RIGHT                  "Move_Right"
    64 #define IPT_MOVE_UP                             "Move_Up"
    65 #define IPT_MOVE_DOWN                   "Move_Down"
    66 #define IPT_MOVE_JUMP                   "Move_Jump"
     52#define USE_WALL        1
     53#define USE_PLATFORM    1
     54#define USE_ROPE        0
     55#define USE_BODIES        1
     56#define USE_ROTATION    0
     57#define USE_CHARACTER    1
     58#define USE_STAIRS        1
     59
     60#define    IPT_MOVE_FORWARD        "Move_Forward"
     61#define    IPT_MOVE_BACKWARD        "Move_Backward"
     62#define    IPT_MOVE_LEFT            "Move_Left"
     63#define    IPT_MOVE_RIGHT            "Move_Right"
     64#define    IPT_MOVE_UP                "Move_Up"
     65#define    IPT_MOVE_DOWN            "Move_Down"
     66#define    IPT_MOVE_JUMP            "Move_Jump"
    6767
    6868BtPhysTest::BtPhysTest(bool editor)
    6969{
    70         m_loop_value = .0f;
     70    m_loop_value = .0f;
    7171
    7272    /* Create a camera that matches the settings of XNA BtPhysTest */
     
    7676    m_camera->SetRotation(quat::fromeuler_xyz(0.f, 0.f, 0.f));
    7777    m_camera->SetPerspective(45.f, 1280.f, 960.f, .1f, 1000.f);
    78         //m_camera->SetOrtho(1280.f / 6, 960.f / 6, -1000.f, 1000.f);
     78    //m_camera->SetOrtho(1280.f / 6, 960.f / 6, -1000.f, 1000.f);
    7979    Ticker::Ref(m_camera);
    8080
    8181    m_ready = false;
    8282
    83         m_simulation = new Simulation();
    84         m_simulation->SetWorldLimit(vec3(-1000.0f, -1000.0f, -1000.0f), vec3(1000.0f, 1000.0f, 1000.0f));
    85         m_simulation->Init();
    86         vec3 NewGravity = vec3(.0f, -10.0f, .0f);
    87         m_simulation->SetGravity(NewGravity);
    88         m_simulation->SetContinuousDetection(true);
    89         m_simulation->SetTimestep(1.f / 120.f);
     83    m_simulation = new Simulation();
     84    m_simulation->SetWorldLimit(vec3(-1000.0f, -1000.0f, -1000.0f), vec3(1000.0f, 1000.0f, 1000.0f));
     85    m_simulation->Init();
     86    vec3 NewGravity = vec3(.0f, -10.0f, .0f);
     87    m_simulation->SetGravity(NewGravity);
     88    m_simulation->SetContinuousDetection(true);
     89    m_simulation->SetTimestep(1.f / 120.f);
    9090    Ticker::Ref(m_simulation);
    9191
    92         float offset = 29.5f;
    93         vec3 pos_offset = vec3(.0f, 30.f, .0f);
    94         if (USE_STAIRS)
    95         {
    96                 vec3 new_offset = vec3(1.0f, .125f, .0f);
    97                 quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
    98                 vec3 NewPosition = pos_offset + vec3(5.0f, -29.f, 15.0f);
    99                 {
    100                         NewRotation = quat::fromeuler_xyz(0.f, 0.f, 30.f);
    101                         NewPosition += vec3(4.0f, .0f, -4.0f);
    102 
    103                         PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
    104                         Ticker::Ref(NewPhyobj);
    105                         m_stairs_list << NewPhyobj;
    106                 }
    107                 {
    108                         NewRotation = quat::fromeuler_xyz(0.f, 0.f, 40.f);
    109                         NewPosition += vec3(4.0f, .0f, -4.0f);
    110 
    111                         PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
    112                         Ticker::Ref(NewPhyobj);
    113                         m_stairs_list << NewPhyobj;
    114                 }
    115                 NewPosition = pos_offset + vec3(5.0f, -29.5f, 15.0f);
    116                 NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
    117                 for (int i=0; i < 15; i++)
    118                 {
    119                         NewPosition += new_offset;
    120 
    121                         PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
    122                         Ticker::Ref(NewPhyobj);
    123                         m_stairs_list << NewPhyobj;
    124                 }
    125         }
    126 
    127         if (USE_WALL)
    128         {
    129                 for (int i=0; i < 6; i++)
    130                 {
    131                         vec3 NewPosition = vec3(.0f);
    132                         quat NewRotation = quat(1.f);
    133 
    134                         PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation);
    135 
    136                         int idx = i/2;
    137                         NewPosition = pos_offset;
    138                         NewPosition[idx] += offset;
    139                         offset *= -1.f;
    140 
    141                         if (idx != 1)
    142                         {
    143                                 vec3 NewAxis = vec3(.0f);
    144                                 NewAxis[2 - idx] = 1;
    145                                 NewRotation = quat::rotate(90.f, NewAxis);
    146                         }
    147 
    148                         NewPhyobj->SetTransform(NewPosition, NewRotation);
    149                         Ticker::Ref(NewPhyobj);
    150                         m_ground_list << NewPhyobj;
    151                 }
    152         }
    153 
    154         PhysicsObject* BasePhyobj = NULL;
    155         if (USE_PLATFORM)
    156         {
    157                 quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
    158                 vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f);
    159 
    160                 PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
    161 
    162                 m_platform_list << NewPhyobj;
    163                 Ticker::Ref(NewPhyobj);
    164 
    165                 NewPosition = pos_offset + vec3(-15.0f, -25.0f, 5.0f);
    166 
    167                 NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
    168                 BasePhyobj = NewPhyobj;
    169 
    170                 m_platform_list << NewPhyobj;
    171                 Ticker::Ref(NewPhyobj);
    172 
    173                 NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f);
    174                 NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f);
    175 
    176                 NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
    177 
    178                 NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, true);
    179                 m_platform_list << NewPhyobj;
    180                 Ticker::Ref(NewPhyobj);
    181 
    182                 //NewPosition += vec3(-0.0f, .0f, .0f);
    183                 //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
    184 
    185                 //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false);
    186                 //m_platform_list << NewPhyobj;
    187                 //Ticker::Ref(NewPhyobj);
    188 
    189                 //NewPosition += vec3(-2.0f, .0f, .0f);
    190                 //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
    191 
    192                 //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false);
    193                 //m_platform_list << NewPhyobj;
    194                 //Ticker::Ref(NewPhyobj);
    195         }
    196 
    197         if (USE_CHARACTER)
    198         {
    199                 quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
    200                 vec3 NewPosition = pos_offset + vec3(-5.0f, -10.0f, 15.0f);
    201 
    202                 PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);
    203 
    204                 m_character_list << NewPhyobj;
    205                 Ticker::Ref(NewPhyobj);
    206 
    207 
    208                 Input::LinkActionToKey(IPT_MOVE_FORWARD,                Key::Up);
    209                 Input::LinkActionToKey(IPT_MOVE_BACKWARD,               Key::Down);
    210                 Input::LinkActionToKey(IPT_MOVE_LEFT,                   Key::Left);
    211                 Input::LinkActionToKey(IPT_MOVE_RIGHT,                  Key::Right);
    212                 Input::LinkActionToKey(IPT_MOVE_JUMP,                   Key::Space);
    213                 Input::LinkActionToKey(IPT_MOVE_UP,                             Key::PageUp);
    214                 Input::LinkActionToKey(IPT_MOVE_DOWN,                   Key::PageDown);
    215 
    216                 //NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true);
    217         }
    218 
    219         if (USE_BODIES)
    220         {
    221                 for (int x=0; x < 6; x++)
    222                 {
    223                         for (int y=0; y < 6; y++)
    224                         {
    225                                 for (int z=0; z < 5; z++)
    226                                 {
    227                                         PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
    228                                                 vec3(-20.f, 15.f, -20.f) +
    229                                                 vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z));
    230                                         m_physobj_list << new_physobj;
    231                                         Ticker::Ref(new_physobj);
    232                                 }
    233                         }
    234                 }
    235         }
    236 
    237         if (USE_ROPE)
    238         {
    239                 Array<PhysicsObject*> RopeElements;
    240                 for (int i = 0; i < 14; i++)
    241                 {
    242                         PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
    243                                 vec3(0.f, 15.f, -20.f) +
    244                                 vec3(0.f, 0.f, 2.f * (float)i), 1);
    245                         RopeElements << new_physobj;
    246                         m_physobj_list << new_physobj;
    247                         Ticker::Ref(new_physobj);
    248                         if (RopeElements.Count() > 1)
    249                         {
    250                                 EasyConstraint* new_constraint = new EasyConstraint();
    251 
    252                                 vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform().v3.xyz -
    253                                                         RopeElements[i - 1]->GetPhysic()->GetTransform().v3.xyz);
    254                                 new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B));
    255                                 new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B));
    256                                 new_constraint->InitConstraintToPoint2Point();
    257                                 new_constraint->DisableCollisionBetweenObjs(true);
    258                                 new_constraint->AddToSimulation(m_simulation);
    259                                 m_constraint_list << new_constraint;
    260                         }
    261                 }
    262         }
     92    float offset = 29.5f;
     93    vec3 pos_offset = vec3(.0f, 30.f, .0f);
     94    if (USE_STAIRS)
     95    {
     96        vec3 new_offset = vec3(1.0f, .125f, .0f);
     97        quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
     98        vec3 NewPosition = pos_offset + vec3(5.0f, -29.f, 15.0f);
     99        {
     100            NewRotation = quat::fromeuler_xyz(0.f, 0.f, 30.f);
     101            NewPosition += vec3(4.0f, .0f, -4.0f);
     102
     103            PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
     104            Ticker::Ref(NewPhyobj);
     105            m_stairs_list << NewPhyobj;
     106        }
     107        {
     108            NewRotation = quat::fromeuler_xyz(0.f, 0.f, 40.f);
     109            NewPosition += vec3(4.0f, .0f, -4.0f);
     110
     111            PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
     112            Ticker::Ref(NewPhyobj);
     113            m_stairs_list << NewPhyobj;
     114        }
     115        NewPosition = pos_offset + vec3(5.0f, -29.5f, 15.0f);
     116        NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
     117        for (int i=0; i < 15; i++)
     118        {
     119            NewPosition += new_offset;
     120
     121            PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 3);
     122            Ticker::Ref(NewPhyobj);
     123            m_stairs_list << NewPhyobj;
     124        }
     125    }
     126
     127    if (USE_WALL)
     128    {
     129        for (int i=0; i < 6; i++)
     130        {
     131            vec3 NewPosition = vec3(.0f);
     132            quat NewRotation = quat(1.f);
     133
     134            PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation);
     135
     136            int idx = i/2;
     137            NewPosition = pos_offset;
     138            NewPosition[idx] += offset;
     139            offset *= -1.f;
     140
     141            if (idx != 1)
     142            {
     143                vec3 NewAxis = vec3(.0f);
     144                NewAxis[2 - idx] = 1;
     145                NewRotation = quat::rotate(90.f, NewAxis);
     146            }
     147
     148            NewPhyobj->SetTransform(NewPosition, NewRotation);
     149            Ticker::Ref(NewPhyobj);
     150            m_ground_list << NewPhyobj;
     151        }
     152    }
     153
     154    PhysicsObject* BasePhyobj = NULL;
     155    if (USE_PLATFORM)
     156    {
     157        quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
     158        vec3 NewPosition = pos_offset + vec3(5.0f, -25.0f, -15.0f);
     159
     160        PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
     161
     162        m_platform_list << NewPhyobj;
     163        Ticker::Ref(NewPhyobj);
     164
     165        NewPosition = pos_offset + vec3(-15.0f, -25.0f, 5.0f);
     166
     167        NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
     168        BasePhyobj = NewPhyobj;
     169
     170        m_platform_list << NewPhyobj;
     171        Ticker::Ref(NewPhyobj);
     172
     173        NewRotation = quat::fromeuler_xyz(0.f, 0.f, 90.f);
     174        NewPosition = pos_offset + vec3(-20.0f, -25.0f, 5.0f);
     175
     176        NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
     177
     178        NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, true);
     179        m_platform_list << NewPhyobj;
     180        Ticker::Ref(NewPhyobj);
     181
     182        //NewPosition += vec3(-0.0f, .0f, .0f);
     183        //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
     184
     185        //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), true, false);
     186        //m_platform_list << NewPhyobj;
     187        //Ticker::Ref(NewPhyobj);
     188
     189        //NewPosition += vec3(-2.0f, .0f, .0f);
     190        //NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 1);
     191
     192        //NewPhyobj->GetPhysic()->AttachTo(BasePhyobj->GetPhysic(), false, false);
     193        //m_platform_list << NewPhyobj;
     194        //Ticker::Ref(NewPhyobj);
     195    }
     196
     197    if (USE_CHARACTER)
     198    {
     199        quat NewRotation = quat::fromeuler_xyz(0.f, 0.f, 0.f);
     200        vec3 NewPosition = pos_offset + vec3(-5.0f, -10.0f, 15.0f);
     201
     202        PhysicsObject* NewPhyobj = new PhysicsObject(m_simulation, NewPosition, NewRotation, 2);
     203
     204        m_character_list << NewPhyobj;
     205        Ticker::Ref(NewPhyobj);
     206
     207
     208        Input::LinkActionToKey(IPT_MOVE_FORWARD,        Key::Up);
     209        Input::LinkActionToKey(IPT_MOVE_BACKWARD,        Key::Down);
     210        Input::LinkActionToKey(IPT_MOVE_LEFT,            Key::Left);
     211        Input::LinkActionToKey(IPT_MOVE_RIGHT,            Key::Right);
     212        Input::LinkActionToKey(IPT_MOVE_JUMP,            Key::Space);
     213        Input::LinkActionToKey(IPT_MOVE_UP,                Key::PageUp);
     214        Input::LinkActionToKey(IPT_MOVE_DOWN,            Key::PageDown);
     215
     216        //NewPhyobj->GetCharacter()->AttachTo(BasePhyobj->GetPhysic(), true, true);
     217    }
     218
     219    if (USE_BODIES)
     220    {
     221        for (int x=0; x < 6; x++)
     222        {
     223            for (int y=0; y < 6; y++)
     224            {
     225                for (int z=0; z < 5; z++)
     226                {
     227                    PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
     228                        vec3(-20.f, 15.f, -20.f) +
     229                        vec3(8.f * (float)x, 8.f * (float)y, 8.f * (float)z));
     230                    m_physobj_list << new_physobj;
     231                    Ticker::Ref(new_physobj);
     232                }
     233            }
     234        }
     235    }
     236
     237    if (USE_ROPE)
     238    {
     239        Array<PhysicsObject*> RopeElements;
     240        for (int i = 0; i < 14; i++)
     241        {
     242            PhysicsObject* new_physobj = new PhysicsObject(m_simulation, 1000.f,
     243                vec3(0.f, 15.f, -20.f) +
     244                vec3(0.f, 0.f, 2.f * (float)i), 1);
     245            RopeElements << new_physobj;
     246            m_physobj_list << new_physobj;
     247            Ticker::Ref(new_physobj);
     248            if (RopeElements.Count() > 1)
     249            {
     250                EasyConstraint* new_constraint = new EasyConstraint();
     251
     252                vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform().v3.xyz -
     253                            RopeElements[i - 1]->GetPhysic()->GetTransform().v3.xyz);
     254                new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B));
     255                new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B));
     256                new_constraint->InitConstraintToPoint2Point();
     257                new_constraint->DisableCollisionBetweenObjs(true);
     258                new_constraint->AddToSimulation(m_simulation);
     259                m_constraint_list << new_constraint;
     260            }
     261        }
     262    }
    263263}
    264264
     
    270270        Ticker::Shutdown();
    271271
    272         m_loop_value += seconds;
    273         if (m_loop_value > M_PI * 2.0f)
    274                 m_loop_value -= M_PI * 2.0f;
    275 
    276         vec3 GroundBarycenter = vec3(.0f);
    277         vec3 PhysObjBarycenter = vec3(.0f);
    278         float factor = .0f;
    279 
    280         if (USE_WALL)
    281         {
    282                 for (int i = 0; i < m_ground_list.Count(); i++)
    283                 {
    284                         PhysicsObject* PhysObj = m_ground_list[i];
    285                         mat4 GroundMat = PhysObj->GetTransform();
    286 
    287                         GroundBarycenter += GroundMat.v3.xyz;
    288                         factor += 1.f;
    289                 }
    290 
    291                 GroundBarycenter /= factor;
    292 
    293                 for (int i = 0; i < m_ground_list.Count(); i++)
    294                 {
    295                         PhysicsObject* PhysObj = m_ground_list[i];
    296 
    297                         mat4 GroundMat = PhysObj->GetTransform();
    298                         vec3 CenterToGround = GroundMat.v3.xyz - GroundBarycenter;
    299                         vec3 CenterToCam = m_camera->m_position - GroundBarycenter;
    300 
    301                         if (dot(normalize(CenterToCam - CenterToGround),
    302                                         normalize(CenterToGround)) > 0.f)
    303                                 PhysObj->SetRender(false);
    304                         else
    305                                 PhysObj->SetRender(true);
    306                 }
    307         }
    308 
    309         if (USE_ROTATION)
    310         {
    311                 for (int i = 0; i < m_ground_list.Count(); i++)
    312                 {
    313                         PhysicsObject* PhysObj = m_ground_list[i];
    314 
    315                         mat4 GroundMat = PhysObj->GetTransform();
    316                         mat4 CenterMx = mat4::translate(GroundBarycenter);
    317                         GroundMat = inverse(CenterMx) * GroundMat;
    318                         GroundMat = CenterMx *
    319                                                 mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds))
    320                                                 * GroundMat;
    321                         PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
    322                 }
    323         }
    324 
    325         if (USE_PLATFORM)
    326         {
    327                 for (int i = 0; i < m_platform_list.Count(); i++)
    328                 {
    329                         PhysicsObject* PhysObj = m_platform_list[i];
    330 
    331                         mat4 GroundMat = PhysObj->GetTransform();
    332                         if (i == 0)
    333                         {
    334                                 GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds));
    335                                 PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
    336                         }
    337                         else if (i == 1)
    338                         {
    339                                 GroundMat =
    340                                         mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) *
    341                                         mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f)));
    342                                 PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
    343                         }
    344                 }
    345         }
    346 
    347         if (USE_CHARACTER)
    348         {
    349                 for (int i = 0; i < m_character_list.Count(); i++)
    350                 {
    351                         PhysicsObject* PhysObj = m_character_list[i];
    352                         EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
    353                         mat4 CtlrMx = Character->GetTransform();
    354                        
    355                         int HMovement = Input::GetStatus(IPT_MOVE_RIGHT) - Input::GetStatus(IPT_MOVE_LEFT);
    356                         int VMovement = Input::GetStatus(IPT_MOVE_FORWARD) - Input::GetStatus(IPT_MOVE_BACKWARD);
    357                         int RMovement = Input::GetStatus(IPT_MOVE_UP) - Input::GetStatus(IPT_MOVE_DOWN);
    358                         vec3 CharMove = vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f);
    359 
    360                         if (Input::WasReleased(IPT_MOVE_JUMP))
    361                                 Character->Jump();
    362                         Character->SetMovementForFrame(CharMove);
    363 
    364                         RayCastResult HitResult;
    365                         if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform().v3.xyz, (Character->GetTransform().v3.xyz + vec3(.0f, -1.f, .0f)), Character))
    366                                 Character->AttachTo(HitResult.m_collider_list[0], true, true);
    367                         else
    368                                 Character->AttachTo(NULL);
    369                 }
    370         }
    371 
    372         if (USE_CHARACTER)
    373         {
    374                 PhysObjBarycenter = vec3(.0f);
    375                 factor = .0f;
    376 
    377                 for (int i = 0; i < m_character_list.Count(); i++)
    378                 {
    379                         PhysicsObject* PhysObj = m_character_list[i];
    380                         mat4 GroundMat = PhysObj->GetTransform();
    381 
    382                         PhysObjBarycenter += GroundMat.v3.xyz;
    383                         factor += 1.f;
    384                 }
    385 
    386                 PhysObjBarycenter /= factor;
    387 
    388                 m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
    389                 vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 5.0f, .0f);
    390                 m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f);
    391         }
    392         else
    393         {
    394                 PhysObjBarycenter = vec3(.0f);
    395                 for (int i = 0; i < m_physobj_list.Count(); i++)
    396                 {
    397                         PhysicsObject* PhysObj = m_physobj_list[i];
    398                         mat4 GroundMat = PhysObj->GetTransform();
    399 
    400                         PhysObjBarycenter += GroundMat.v3.xyz;
    401                         factor += 1.f;
    402                 }
    403 
    404                 PhysObjBarycenter /= factor;
    405 
    406                 m_camera->SetTarget(PhysObjBarycenter);
    407                 m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
    408         }
     272    m_loop_value += seconds;
     273    if (m_loop_value > M_PI * 2.0f)
     274        m_loop_value -= M_PI * 2.0f;
     275
     276    vec3 GroundBarycenter = vec3(.0f);
     277    vec3 PhysObjBarycenter = vec3(.0f);
     278    float factor = .0f;
     279
     280    if (USE_WALL)
     281    {
     282        for (int i = 0; i < m_ground_list.Count(); i++)
     283        {
     284            PhysicsObject* PhysObj = m_ground_list[i];
     285            mat4 GroundMat = PhysObj->GetTransform();
     286
     287            GroundBarycenter += GroundMat.v3.xyz;
     288            factor += 1.f;
     289        }
     290
     291        GroundBarycenter /= factor;
     292
     293        for (int i = 0; i < m_ground_list.Count(); i++)
     294        {
     295            PhysicsObject* PhysObj = m_ground_list[i];
     296
     297            mat4 GroundMat = PhysObj->GetTransform();
     298            vec3 CenterToGround = GroundMat.v3.xyz - GroundBarycenter;
     299            vec3 CenterToCam = m_camera->m_position - GroundBarycenter;
     300
     301            if (dot(normalize(CenterToCam - CenterToGround),
     302                    normalize(CenterToGround)) > 0.f)
     303                PhysObj->SetRender(false);
     304            else
     305                PhysObj->SetRender(true);
     306        }
     307    }
     308
     309    if (USE_ROTATION)
     310    {
     311        for (int i = 0; i < m_ground_list.Count(); i++)
     312        {
     313            PhysicsObject* PhysObj = m_ground_list[i];
     314
     315            mat4 GroundMat = PhysObj->GetTransform();
     316            mat4 CenterMx = mat4::translate(GroundBarycenter);
     317            GroundMat = inverse(CenterMx) * GroundMat;
     318            GroundMat = CenterMx *
     319                        mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds))
     320                        * GroundMat;
     321            PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
     322        }
     323    }
     324
     325    if (USE_PLATFORM)
     326    {
     327        for (int i = 0; i < m_platform_list.Count(); i++)
     328        {
     329            PhysicsObject* PhysObj = m_platform_list[i];
     330
     331            mat4 GroundMat = PhysObj->GetTransform();
     332            if (i == 0)
     333            {
     334                GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds));
     335                PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
     336            }
     337            else if (i == 1)
     338            {
     339                GroundMat =
     340                    mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) *
     341                    mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f)));
     342                PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat));
     343            }
     344        }
     345    }
     346
     347    if (USE_CHARACTER)
     348    {
     349        for (int i = 0; i < m_character_list.Count(); i++)
     350        {
     351            PhysicsObject* PhysObj = m_character_list[i];
     352            EasyCharacterController* Character = (EasyCharacterController*)PhysObj->GetCharacter();
     353            mat4 CtlrMx = Character->GetTransform();
     354
     355            int HMovement = Input::GetStatus(IPT_MOVE_RIGHT) - Input::GetStatus(IPT_MOVE_LEFT);
     356            int VMovement = Input::GetStatus(IPT_MOVE_FORWARD) - Input::GetStatus(IPT_MOVE_BACKWARD);
     357            int RMovement = Input::GetStatus(IPT_MOVE_UP) - Input::GetStatus(IPT_MOVE_DOWN);
     358            vec3 CharMove = vec3((float)VMovement * seconds * 4.f, (float)RMovement * seconds * 10.f, (float)HMovement * seconds * 4.f);
     359
     360            if (Input::WasReleased(IPT_MOVE_JUMP))
     361                Character->Jump();
     362            Character->SetMovementForFrame(CharMove);
     363
     364            RayCastResult HitResult;
     365            if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform().v3.xyz, (Character->GetTransform().v3.xyz + vec3(.0f, -1.f, .0f)), Character))
     366                Character->AttachTo(HitResult.m_collider_list[0], true, true);
     367            else
     368                Character->AttachTo(NULL);
     369        }
     370    }
     371
     372    if (USE_CHARACTER)
     373    {
     374        PhysObjBarycenter = vec3(.0f);
     375        factor = .0f;
     376
     377        for (int i = 0; i < m_character_list.Count(); i++)
     378        {
     379            PhysicsObject* PhysObj = m_character_list[i];
     380            mat4 GroundMat = PhysObj->GetTransform();
     381
     382            PhysObjBarycenter += GroundMat.v3.xyz;
     383            factor += 1.f;
     384        }
     385
     386        PhysObjBarycenter /= factor;
     387
     388        m_camera->SetTarget(m_camera->GetTarget() + (seconds / (seconds + 0.18f)) * (PhysObjBarycenter - m_camera->GetTarget()));
     389        vec3 CamPosCenter = m_camera->GetTarget() + vec3(.0f, 5.0f, .0f);
     390        m_camera->SetPosition(CamPosCenter + normalize(m_camera->GetPosition() - CamPosCenter) * 20.0f);
     391    }
     392    else
     393    {
     394        PhysObjBarycenter = vec3(.0f);
     395        for (int i = 0; i < m_physobj_list.Count(); i++)
     396        {
     397            PhysicsObject* PhysObj = m_physobj_list[i];
     398            mat4 GroundMat = PhysObj->GetTransform();
     399
     400            PhysObjBarycenter += GroundMat.v3.xyz;
     401            factor += 1.f;
     402        }
     403
     404        PhysObjBarycenter /= factor;
     405
     406        m_camera->SetTarget(PhysObjBarycenter);
     407        m_camera->SetPosition(GroundBarycenter + normalize(GroundBarycenter - PhysObjBarycenter) * 60.0f);
     408    }
    409409
    410410}
     
    426426BtPhysTest::~BtPhysTest()
    427427{
    428         Ticker::Unref(m_camera);
    429        
    430         while (m_constraint_list.Count())
    431         {
    432                 EasyConstraint* CurPop = m_constraint_list.Last();
    433                 m_constraint_list.Pop();
    434                 CurPop->RemoveFromSimulation(m_simulation);
    435                 delete CurPop;
    436         }
    437         while (m_ground_list.Count())
    438         {
    439                 PhysicsObject* CurPop = m_ground_list.Last();
    440                 m_ground_list.Pop();
    441                 CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
    442                 Ticker::Unref(CurPop);
    443         }
    444         while (m_stairs_list.Count())
    445         {
    446                 PhysicsObject* CurPop = m_stairs_list.Last();
    447                 m_stairs_list.Pop();
    448                 CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
    449                 Ticker::Unref(CurPop);
    450         }
    451         while (m_character_list.Count())
    452         {
    453                 PhysicsObject* CurPop = m_character_list.Last();
    454                 m_character_list.Pop();
    455                 CurPop->GetCharacter()->RemoveFromSimulation(m_simulation);
    456                 Ticker::Unref(CurPop);
    457         }
    458         while (m_platform_list.Count())
    459         {
    460                 PhysicsObject* CurPop = m_platform_list.Last();
    461                 m_platform_list.Pop();
    462                 CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
    463                 Ticker::Unref(CurPop);
    464         }
    465         while (m_physobj_list.Count())
    466         {
    467                 PhysicsObject* CurPop = m_physobj_list.Last();
    468                 m_physobj_list.Pop();
    469                 CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
    470                 Ticker::Unref(CurPop);
    471         }
     428    Ticker::Unref(m_camera);
     429
     430    while (m_constraint_list.Count())
     431    {
     432        EasyConstraint* CurPop = m_constraint_list.Last();
     433        m_constraint_list.Pop();
     434        CurPop->RemoveFromSimulation(m_simulation);
     435        delete CurPop;
     436    }
     437    while (m_ground_list.Count())
     438    {
     439        PhysicsObject* CurPop = m_ground_list.Last();
     440        m_ground_list.Pop();
     441        CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
     442        Ticker::Unref(CurPop);
     443    }
     444    while (m_stairs_list.Count())
     445    {
     446        PhysicsObject* CurPop = m_stairs_list.Last();
     447        m_stairs_list.Pop();
     448        CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
     449        Ticker::Unref(CurPop);
     450    }
     451    while (m_character_list.Count())
     452    {
     453        PhysicsObject* CurPop = m_character_list.Last();
     454        m_character_list.Pop();
     455        CurPop->GetCharacter()->RemoveFromSimulation(m_simulation);
     456        Ticker::Unref(CurPop);
     457    }
     458    while (m_platform_list.Count())
     459    {
     460        PhysicsObject* CurPop = m_platform_list.Last();
     461        m_platform_list.Pop();
     462        CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
     463        Ticker::Unref(CurPop);
     464    }
     465    while (m_physobj_list.Count())
     466    {
     467        PhysicsObject* CurPop = m_physobj_list.Last();
     468        m_physobj_list.Pop();
     469        CurPop->GetPhysic()->RemoveFromSimulation(m_simulation);
     470        Ticker::Unref(CurPop);
     471    }
    472472    Ticker::Unref(m_simulation);
    473473
  • trunk/test/BtPhysTest.h

    r1844 r1888  
    2222
    2323private:
    24     Camera*                                                             m_camera;
    25     bool                                                                m_ready;
     24    Camera*                                m_camera;
     25    bool                                m_ready;
    2626
    27         lol::phys::Simulation*                          m_simulation;
    28         Array<EasyConstraint*>                          m_constraint_list;
    29         Array<PhysicsObject*>                           m_physobj_list;
    30         Array<PhysicsObject*>                           m_ground_list;
    31         Array<PhysicsObject*>                           m_platform_list;
    32         Array<PhysicsObject*>                           m_character_list;
    33         Array<PhysicsObject*>                           m_stairs_list;
     27    lol::phys::Simulation*                m_simulation;
     28    Array<EasyConstraint*>                m_constraint_list;
     29    Array<PhysicsObject*>                m_physobj_list;
     30    Array<PhysicsObject*>                m_ground_list;
     31    Array<PhysicsObject*>                m_platform_list;
     32    Array<PhysicsObject*>                m_character_list;
     33    Array<PhysicsObject*>                m_stairs_list;
    3434
    35         float                                                           m_loop_value;
     35    float                                m_loop_value;
    3636};
    3737
  • trunk/test/PhysicObject.h

    r1845 r1888  
    2424{
    2525public:
    26         PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation)
    27                 : m_ready(false), m_should_render(true), m_is_character(false)
    28         {
    29                 m_physics = new EasyPhysic(this);
    30 
    31                 m_mesh.Compile("[sc#ddd afcb60 1 60 -.1]");
    32                 vec3 BoxSize = vec3(60.f, 1.f, 60.f);
    33                 m_physics->SetCollisionChannel(0, 0xFF);
    34                 m_physics->SetShapeToBox(BoxSize);
    35                 m_physics->SetMass(.0f);
    36                 m_physics->SetTransform(base_location, base_rotation);
    37                 m_physics->InitBodyToRigid(true);
    38                 m_physics->AddToSimulation(new_sim);
    39         }
    40 
    41         PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation, int dummy)
    42                 : m_ready(false), m_should_render(true), m_is_character(false)
    43         {
    44                 if (dummy == 1) //for platform purpose
    45                 {
    46                         m_physics = new EasyPhysic(this);
    47 
    48                         m_mesh.Compile("[sc#ddd afcb20 1 20 -.1]");
    49                         vec3 BoxSize = vec3(20.f, 1.f, 20.f);
    50                         m_physics->SetCollisionChannel(0, 0xFF);
    51                         m_physics->SetShapeToBox(BoxSize);
    52                         m_physics->SetMass(.0f);
    53                         m_physics->SetTransform(base_location, base_rotation);
    54                         m_physics->InitBodyToRigid(true);
    55                         m_physics->AddToSimulation(new_sim);
    56                 }
    57                 else if (dummy == 2) //for character purpose
    58                 {
    59                         m_character = new EasyCharacterController(this);
    60                         m_is_character = true;
    61                         //m_mesh.Compile("[sc#f00 afcb10 10 10 -.1]");
    62                         m_mesh.Compile(
    63                                 "[sc#000 scb#000"
    64                                 //"[sc#aaa scb#aaa"
    65                                 "[ad8 2 0 rx180 ty-1]"
    66                                 "[asph8 .5 .5 .5 ty1]"
    67                                 "[ac32 2 .5 .5 0 0]"
    68                                 "[asph6 .1 .1 .1 ty.9 tx.5 tz.15]"
    69                                 "[asph6 .1 .1 .1 ty.9 tx.5 tz-.15]"
    70                                 "[asph8 .05 .5 .05 ty.6 tz.5]"
    71                                 "[asph8 .05 .5 .05 ty.6 tz-.5]"
    72                                 "]"
    73                                 "[sc#fd0 scb#fd0"
    74                                 "[ac8 .4 .1 0 0 0 ty.25 rz-90 ty.7 tx.5]"
    75                                 "]"
    76                                 "["
    77                                 "[sc#fff scb#fff"
    78                                 "[ad8 2 0 rx180 ty-1]"
    79                                 "[asph8 .5 .5 .5 ty1]"
    80                                 "[ac32 1.9 .5 .5 0 0]"
    81                                 "]"
    82                                 " ty-.1 tx.05]"
    83                                 );
    84                         vec3 BoxSize = vec3(1.f, 2.f, 1.f);
    85                         m_character->SetCollisionChannel(0, 0xFF);
    86                         m_character->SetShapeToCapsule(BoxSize.x, BoxSize.y);
    87                         m_character->SetMass(.0f);
    88                         //m_character->SetStepHeight(1.f);
    89                         m_character->SetTransform(base_location, base_rotation);
    90                         m_character->InitBodyToGhost();
    91                         m_character->AddToSimulation(new_sim);
    92                 }
    93                 else if (dummy == 3) //for Stairs purpose
    94                 {
    95                         m_physics = new EasyPhysic(this);
    96 
    97                         m_mesh.Compile("[sc#aae afcb4 .25 4 -.01]");
    98                         vec3 BoxSize = vec3(4.f, .25f, 4.f);
    99                         m_physics->SetCollisionChannel(0, 0xFF);
    100                         m_physics->SetShapeToBox(BoxSize);
    101                         m_physics->SetMass(.0f);
    102                         m_physics->SetTransform(base_location, base_rotation);
    103                         m_physics->InitBodyToRigid(true);
    104                         m_physics->AddToSimulation(new_sim);
    105                 }
    106         }
    107 
    108         PhysicsObject(Simulation* new_sim, float base_mass, const vec3 &base_location, int RandValue = -1)
    109                 : m_ready(false), m_should_render(true), m_is_character(false)
    110         {
    111                 Array<char const *> MeshRand;
    112 
    113                 //MeshRand << "[sc#add afcb2 2 2 -.1]";
    114                 //MeshRand << "[sc#dad afcb2 2 2 -.1]";
    115                 //MeshRand << "[sc#dda afcb2 2 2 -.1]";
    116                 //MeshRand << "[sc#daa afcb2 2 2 -.1]";
    117                 //MeshRand << "[sc#ada afcb2 2 2 -.1]";
    118                 //MeshRand << "[sc#aad afcb2 2 2 -.1]";
    119                 MeshRand << "[sc#add afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
    120                 MeshRand << "[sc#dad afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
    121                 MeshRand << "[sc#dda afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
    122                 MeshRand << "[sc#daa afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
    123                 MeshRand << "[sc#ada afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
    124                 MeshRand << "[sc#aad afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
    125 
    126                 int SphereLimit = MeshRand.Count();
    127 
    128                 MeshRand << "[sc#add asph1 2 2 2]";
    129                 MeshRand << "[sc#dad asph1 2 2 2]";
    130                 MeshRand << "[sc#dda asph1 2 2 2]";
    131                 MeshRand << "[sc#daa asph1 2 2 2]";
    132                 MeshRand << "[sc#ada asph1 2 2 2]";
    133                 MeshRand << "[sc#aad asph1 2 2 2]";
    134 
    135                 int ConeLimit = MeshRand.Count();
    136 
    137                 MeshRand << "[sc#add scb#add ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
    138                 MeshRand << "[sc#dad scb#dad ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
    139                 MeshRand << "[sc#dda scb#dda ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
    140                 MeshRand << "[sc#daa scb#daa ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
    141                 MeshRand << "[sc#ada scb#ada ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
    142                 MeshRand << "[sc#aad scb#aad ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
    143 
    144                 int CylLimit = MeshRand.Count();
    145 
    146                 MeshRand << "[sc#add scb#add ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
    147                 MeshRand << "[sc#dad scb#dad ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
    148                 MeshRand << "[sc#dda scb#dda ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
    149                 MeshRand << "[sc#daa scb#daa ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
    150                 MeshRand << "[sc#ada scb#ada ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
    151                 MeshRand << "[sc#aad scb#aad ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
    152 
    153                 int CapsLimit = MeshRand.Count();
    154 
    155                 MeshRand << "[sc#add scb#add acap1 2 1]";
    156                 MeshRand << "[sc#dad scb#dad acap1 2 1]";
    157                 MeshRand << "[sc#dda scb#dda acap1 2 1]";
    158                 MeshRand << "[sc#daa scb#daa acap1 2 1]";
    159                 MeshRand << "[sc#ada scb#ada acap1 2 1]";
    160                 MeshRand << "[sc#aad scb#aad acap1 2 1]";
    161 
    162                 switch (RandValue)
    163                 {
    164                         case 0:
    165                         {
    166                                 RandValue = (int)(lol::RandF() * (SphereLimit - 1));
    167                                 break;
    168                         }
    169                         case 1:
    170                         {
    171                                 RandValue = SphereLimit + (int)(lol::RandF() * ((ConeLimit - SphereLimit) - 1));
    172                                 break;
    173                         }
    174                         case 2:
    175                         {
    176                                 RandValue = ConeLimit + (int)(lol::RandF() * ((CylLimit - ConeLimit) - 1));
    177                                 break;
    178                         }
    179                         case 3:
    180                         {
    181                                 RandValue = CylLimit + (int)(lol::RandF() * ((CapsLimit - CylLimit) - 1));
    182                                 break;
    183                         }
    184                         case 4:
    185                         {
    186                                 RandValue = CapsLimit + (int)(lol::RandF() * ((MeshRand.Count() - CapsLimit) - 1));
    187                                 break;
    188                         }
    189                         default:
    190                         {
    191                                 RandValue = (int)(lol::RandF() * (MeshRand.Count() - 1));
    192                         }
    193                 }
    194 
    195                 m_physics = new EasyPhysic(this);
    196 
    197                 m_mesh.Compile(MeshRand[RandValue]);
    198                 vec3 BoxSize = vec3(2.0f);
    199                 int ColGroup = 1;
    200                 if (RandValue < SphereLimit)
    201                 {
    202                         m_physics->SetShapeToBox(BoxSize);
    203                         ColGroup += 0;
    204                 }
    205                 else if (RandValue < ConeLimit)
    206                 {
    207                         m_physics->SetShapeToSphere(BoxSize.x * 2.f);
    208                         ColGroup += 1;
    209                 }
    210                 else if (RandValue < CylLimit)
    211                 {
    212                         m_physics->SetShapeToCone(BoxSize.x, BoxSize.y);
    213                         ColGroup += 2;
    214                 }
    215                 else if (RandValue < CapsLimit)
    216                 {
    217                         m_physics->SetShapeToCylinder(BoxSize);
    218                         ColGroup += 3;
    219                 }
    220                 else
    221                 {
    222                         m_physics->SetShapeToCapsule(BoxSize.x, BoxSize.y);
    223                         ColGroup += 4;
    224                 }
    225 
    226                 m_physics->SetCollisionChannel(0, 0xFF);
    227                 //m_physics->SetCollisionChannel(ColGroup, (1<<ColGroup)|(1));
    228                 m_physics->SetMass(base_mass);
    229                 m_physics->SetTransform(base_location);
    230                 m_physics->InitBodyToRigid();
    231                 m_physics->AddToSimulation(new_sim);
    232         }
    233 
    234         void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f)))
    235         {
    236                 if (m_is_character)
    237                         m_character->SetTransform(base_location, base_rotation);
    238                 else
    239                         m_physics->SetTransform(base_location, base_rotation);
    240         }
    241 
    242         lol::mat4 GetTransform()
    243         {
    244                 if (m_is_character)
    245                         return m_character->GetTransform();
    246                 else
    247                         return m_physics->GetTransform();
    248         }
    249 
    250         void SetRender(bool should_render)
    251         {
    252                 m_should_render = should_render;
    253         }
    254 
    255         EasyMesh *GetMesh() { return &m_mesh; }
    256         EasyPhysic *GetPhysic() { return m_physics; }
    257         EasyCharacterController *GetCharacter() { return m_character; }
    258 
    259         ~PhysicsObject()
    260         {
    261         }
    262 
    263         char const *GetName() { return "<PhysicsObject>"; }
     26    PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation)
     27        : m_ready(false), m_should_render(true), m_is_character(false)
     28    {
     29        m_physics = new EasyPhysic(this);
     30
     31        m_mesh.Compile("[sc#ddd afcb60 1 60 -.1]");
     32        vec3 BoxSize = vec3(60.f, 1.f, 60.f);
     33        m_physics->SetCollisionChannel(0, 0xFF);
     34        m_physics->SetShapeToBox(BoxSize);
     35        m_physics->SetMass(.0f);
     36        m_physics->SetTransform(base_location, base_rotation);
     37        m_physics->InitBodyToRigid(true);
     38        m_physics->AddToSimulation(new_sim);
     39    }
     40
     41    PhysicsObject(Simulation* new_sim, const vec3 &base_location, const quat &base_rotation, int dummy)
     42        : m_ready(false), m_should_render(true), m_is_character(false)
     43    {
     44        if (dummy == 1) //for platform purpose
     45        {
     46            m_physics = new EasyPhysic(this);
     47
     48            m_mesh.Compile("[sc#ddd afcb20 1 20 -.1]");
     49            vec3 BoxSize = vec3(20.f, 1.f, 20.f);
     50            m_physics->SetCollisionChannel(0, 0xFF);
     51            m_physics->SetShapeToBox(BoxSize);
     52            m_physics->SetMass(.0f);
     53            m_physics->SetTransform(base_location, base_rotation);
     54            m_physics->InitBodyToRigid(true);
     55            m_physics->AddToSimulation(new_sim);
     56        }
     57        else if (dummy == 2) //for character purpose
     58        {
     59            m_character = new EasyCharacterController(this);
     60            m_is_character = true;
     61            //m_mesh.Compile("[sc#f00 afcb10 10 10 -.1]");
     62            m_mesh.Compile(
     63                "[sc#000 scb#000"
     64                //"[sc#aaa scb#aaa"
     65                "[ad8 2 0 rx180 ty-1]"
     66                "[asph8 .5 .5 .5 ty1]"
     67                "[ac32 2 .5 .5 0 0]"
     68                "[asph6 .1 .1 .1 ty.9 tx.5 tz.15]"
     69                "[asph6 .1 .1 .1 ty.9 tx.5 tz-.15]"
     70                "[asph8 .05 .5 .05 ty.6 tz.5]"
     71                "[asph8 .05 .5 .05 ty.6 tz-.5]"
     72                "]"
     73                "[sc#fd0 scb#fd0"
     74                "[ac8 .4 .1 0 0 0 ty.25 rz-90 ty.7 tx.5]"
     75                "]"
     76                "["
     77                "[sc#fff scb#fff"
     78                "[ad8 2 0 rx180 ty-1]"
     79                "[asph8 .5 .5 .5 ty1]"
     80                "[ac32 1.9 .5 .5 0 0]"
     81                "]"
     82                " ty-.1 tx.05]"
     83                );
     84            vec3 BoxSize = vec3(1.f, 2.f, 1.f);
     85            m_character->SetCollisionChannel(0, 0xFF);
     86            m_character->SetShapeToCapsule(BoxSize.x, BoxSize.y);
     87            m_character->SetMass(.0f);
     88            //m_character->SetStepHeight(1.f);
     89            m_character->SetTransform(base_location, base_rotation);
     90            m_character->InitBodyToGhost();
     91            m_character->AddToSimulation(new_sim);
     92        }
     93        else if (dummy == 3) //for Stairs purpose
     94        {
     95            m_physics = new EasyPhysic(this);
     96
     97            m_mesh.Compile("[sc#aae afcb4 .25 4 -.01]");
     98            vec3 BoxSize = vec3(4.f, .25f, 4.f);
     99            m_physics->SetCollisionChannel(0, 0xFF);
     100            m_physics->SetShapeToBox(BoxSize);
     101            m_physics->SetMass(.0f);
     102            m_physics->SetTransform(base_location, base_rotation);
     103            m_physics->InitBodyToRigid(true);
     104            m_physics->AddToSimulation(new_sim);
     105        }
     106    }
     107
     108    PhysicsObject(Simulation* new_sim, float base_mass, const vec3 &base_location, int RandValue = -1)
     109        : m_ready(false), m_should_render(true), m_is_character(false)
     110    {
     111        Array<char const *> MeshRand;
     112
     113        //MeshRand << "[sc#add afcb2 2 2 -.1]";
     114        //MeshRand << "[sc#dad afcb2 2 2 -.1]";
     115        //MeshRand << "[sc#dda afcb2 2 2 -.1]";
     116        //MeshRand << "[sc#daa afcb2 2 2 -.1]";
     117        //MeshRand << "[sc#ada afcb2 2 2 -.1]";
     118        //MeshRand << "[sc#aad afcb2 2 2 -.1]";
     119        MeshRand << "[sc#add afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
     120        MeshRand << "[sc#dad afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
     121        MeshRand << "[sc#dda afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
     122        MeshRand << "[sc#daa afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
     123        MeshRand << "[sc#ada afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
     124        MeshRand << "[sc#aad afcb1.7 1.7 1.7 0][sc#000 afcb1.9 1.9 1.9 0 sx-1 sy-1 sz-1]";
     125
     126        int SphereLimit = MeshRand.Count();
     127
     128        MeshRand << "[sc#add asph1 2 2 2]";
     129        MeshRand << "[sc#dad asph1 2 2 2]";
     130        MeshRand << "[sc#dda asph1 2 2 2]";
     131        MeshRand << "[sc#daa asph1 2 2 2]";
     132        MeshRand << "[sc#ada asph1 2 2 2]";
     133        MeshRand << "[sc#aad asph1 2 2 2]";
     134
     135        int ConeLimit = MeshRand.Count();
     136
     137        MeshRand << "[sc#add scb#add ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
     138        MeshRand << "[sc#dad scb#dad ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
     139        MeshRand << "[sc#dda scb#dda ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
     140        MeshRand << "[sc#daa scb#daa ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
     141        MeshRand << "[sc#ada scb#ada ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
     142        MeshRand << "[sc#aad scb#aad ad1 2 0 rx180 ty-1 ac4 2 2 0 0 0]";
     143
     144        int CylLimit = MeshRand.Count();
     145
     146        MeshRand << "[sc#add scb#add ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
     147        MeshRand << "[sc#dad scb#dad ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
     148        MeshRand << "[sc#dda scb#dda ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
     149        MeshRand << "[sc#daa scb#daa ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
     150        MeshRand << "[sc#ada scb#ada ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
     151        MeshRand << "[sc#aad scb#aad ad1 2 0 rx180 ty-1 my ac4 2 2 2 0 0]";
     152
     153        int CapsLimit = MeshRand.Count();
     154
     155        MeshRand << "[sc#add scb#add acap1 2 1]";
     156        MeshRand << "[sc#dad scb#dad acap1 2 1]";
     157        MeshRand << "[sc#dda scb#dda acap1 2 1]";
     158        MeshRand << "[sc#daa scb#daa acap1 2 1]";
     159        MeshRand << "[sc#ada scb#ada acap1 2 1]";
     160        MeshRand << "[sc#aad scb#aad acap1 2 1]";
     161
     162        switch (RandValue)
     163        {
     164            case 0:
     165            {
     166                RandValue = (int)(lol::RandF() * (SphereLimit - 1));
     167                break;
     168            }
     169            case 1:
     170            {
     171                RandValue = SphereLimit + (int)(lol::RandF() * ((ConeLimit - SphereLimit) - 1));
     172                break;
     173            }
     174            case 2:
     175            {
     176                RandValue = ConeLimit + (int)(lol::RandF() * ((CylLimit - ConeLimit) - 1));
     177                break;
     178            }
     179            case 3:
     180            {
     181                RandValue = CylLimit + (int)(lol::RandF() * ((CapsLimit - CylLimit) - 1));
     182                break;
     183            }
     184            case 4:
     185            {
     186                RandValue = CapsLimit + (int)(lol::RandF() * ((MeshRand.Count() - CapsLimit) - 1));
     187                break;
     188            }
     189            default:
     190            {
     191                RandValue = (int)(lol::RandF() * (MeshRand.Count() - 1));
     192            }
     193        }
     194
     195        m_physics = new EasyPhysic(this);
     196
     197        m_mesh.Compile(MeshRand[RandValue]);
     198        vec3 BoxSize = vec3(2.0f);
     199        int ColGroup = 1;
     200        if (RandValue < SphereLimit)
     201        {
     202            m_physics->SetShapeToBox(BoxSize);
     203            ColGroup += 0;
     204        }
     205        else if (RandValue < ConeLimit)
     206        {
     207            m_physics->SetShapeToSphere(BoxSize.x * 2.f);
     208            ColGroup += 1;
     209        }
     210        else if (RandValue < CylLimit)
     211        {
     212            m_physics->SetShapeToCone(BoxSize.x, BoxSize.y);
     213            ColGroup += 2;
     214        }
     215        else if (RandValue < CapsLimit)
     216        {
     217            m_physics->SetShapeToCylinder(BoxSize);
     218            ColGroup += 3;
     219        }
     220        else
     221        {
     222            m_physics->SetShapeToCapsule(BoxSize.x, BoxSize.y);
     223            ColGroup += 4;
     224        }
     225
     226        m_physics->SetCollisionChannel(0, 0xFF);
     227        //m_physics->SetCollisionChannel(ColGroup, (1<<ColGroup)|(1));
     228        m_physics->SetMass(base_mass);
     229        m_physics->SetTransform(base_location);
     230        m_physics->InitBodyToRigid();
     231        m_physics->AddToSimulation(new_sim);
     232    }
     233
     234    void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f)))
     235    {
     236        if (m_is_character)
     237            m_character->SetTransform(base_location, base_rotation);
     238        else
     239            m_physics->SetTransform(base_location, base_rotation);
     240    }
     241
     242    lol::mat4 GetTransform()
     243    {
     244        if (m_is_character)
     245            return m_character->GetTransform();
     246        else
     247            return m_physics->GetTransform();
     248    }
     249
     250    void SetRender(bool should_render)
     251    {
     252        m_should_render = should_render;
     253    }
     254
     255    EasyMesh *GetMesh() { return &m_mesh; }
     256    EasyPhysic *GetPhysic() { return m_physics; }
     257    EasyCharacterController *GetCharacter() { return m_character; }
     258
     259    ~PhysicsObject()
     260    {
     261    }
     262
     263    char const *GetName() { return "<PhysicsObject>"; }
    264264
    265265protected:
    266         virtual void TickGame(float seconds)
    267         {
    268                 WorldEntity::TickGame(seconds);
    269         }
    270 
    271         virtual void TickDraw(float seconds)
    272         {
    273                 WorldEntity::TickDraw(seconds);
    274 
    275                 if (!m_ready)
    276                 {
    277                         m_mesh.MeshConvert();
    278                         m_ready = true;
    279                 }
    280 
    281                 if (m_should_render)
    282                 {
    283                         if (m_is_character)
    284                                 m_mesh.Render(m_character->GetTransform());
    285                         else
    286                                 m_mesh.Render(m_physics->GetTransform());
    287                 }
    288         }
     266    virtual void TickGame(float seconds)
     267    {
     268        WorldEntity::TickGame(seconds);
     269    }
     270
     271    virtual void TickDraw(float seconds)
     272    {
     273        WorldEntity::TickDraw(seconds);
     274
     275        if (!m_ready)
     276        {
     277            m_mesh.MeshConvert();
     278            m_ready = true;
     279        }
     280
     281        if (m_should_render)
     282        {
     283            if (m_is_character)
     284                m_mesh.Render(m_character->GetTransform());
     285            else
     286                m_mesh.Render(m_physics->GetTransform());
     287        }
     288    }
    289289
    290290private:
    291         //Base datas
    292         EasyMesh                                        m_mesh;
    293         EasyPhysic*                                     m_physics;
    294         EasyCharacterController*        m_character;
    295 
    296         bool                                            m_ready;
    297         bool                                            m_should_render;
    298         bool                                            m_is_character;
     291    //Base datas
     292    EasyMesh                    m_mesh;
     293    EasyPhysic*                    m_physics;
     294    EasyCharacterController*    m_character;
     295
     296    bool                        m_ready;
     297    bool                        m_should_render;
     298    bool                        m_is_character;
    299299};
    300300
  • 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.