Merge pull request #905 from lunkhound/pr-sel-solver-type
example browser: add controls for changing the solver type and solver flags
This commit is contained in:
@@ -43,6 +43,7 @@ struct ButtonParams
|
|||||||
int m_buttonId;
|
int m_buttonId;
|
||||||
void* m_userPointer;
|
void* m_userPointer;
|
||||||
bool m_isTrigger;
|
bool m_isTrigger;
|
||||||
|
bool m_initialState;
|
||||||
|
|
||||||
ButtonParamChangedCallback m_callback;
|
ButtonParamChangedCallback m_callback;
|
||||||
ButtonParams(const char* name, int buttonId, bool isTrigger)
|
ButtonParams(const char* name, int buttonId, bool isTrigger)
|
||||||
@@ -50,6 +51,7 @@ struct ButtonParams
|
|||||||
m_buttonId(buttonId),
|
m_buttonId(buttonId),
|
||||||
m_userPointer(0),
|
m_userPointer(0),
|
||||||
m_isTrigger(isTrigger),
|
m_isTrigger(isTrigger),
|
||||||
|
m_initialState(false),
|
||||||
m_callback(0)
|
m_callback(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,14 @@
|
|||||||
|
|
||||||
struct MyButtonEventHandler : public Gwen::Event::Handler
|
struct MyButtonEventHandler : public Gwen::Event::Handler
|
||||||
{
|
{
|
||||||
|
Gwen::Controls::Button* m_buttonControl;
|
||||||
ButtonParamChangedCallback m_callback;
|
ButtonParamChangedCallback m_callback;
|
||||||
void* m_userPointer;
|
void* m_userPointer;
|
||||||
int m_buttonId;
|
int m_buttonId;
|
||||||
|
|
||||||
MyButtonEventHandler(ButtonParamChangedCallback callback, int buttonId, void* userPointer)
|
MyButtonEventHandler(Gwen::Controls::Button* buttonControl, ButtonParamChangedCallback callback, int buttonId, void* userPointer)
|
||||||
:m_callback(callback),
|
:m_buttonControl(buttonControl),
|
||||||
|
m_callback(callback),
|
||||||
m_userPointer(userPointer),
|
m_userPointer(userPointer),
|
||||||
m_buttonId(buttonId)
|
m_buttonId(buttonId)
|
||||||
{
|
{
|
||||||
@@ -18,7 +20,12 @@ struct MyButtonEventHandler : public Gwen::Event::Handler
|
|||||||
{
|
{
|
||||||
if (m_callback)
|
if (m_callback)
|
||||||
{
|
{
|
||||||
(*m_callback)(m_buttonId, true, m_userPointer);
|
bool buttonState = true;
|
||||||
|
if (m_buttonControl->IsToggle())
|
||||||
|
{
|
||||||
|
buttonState = m_buttonControl->GetToggleState();
|
||||||
|
}
|
||||||
|
( *m_callback )( m_buttonId, buttonState, m_userPointer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -141,10 +148,11 @@ void GwenParameterInterface::registerButtonParameter(ButtonParams& params)
|
|||||||
{
|
{
|
||||||
|
|
||||||
Gwen::Controls::Button* button = new Gwen::Controls::Button(m_gwenInternalData->m_demoPage->GetPage());
|
Gwen::Controls::Button* button = new Gwen::Controls::Button(m_gwenInternalData->m_demoPage->GetPage());
|
||||||
MyButtonEventHandler* handler = new MyButtonEventHandler(params.m_callback,params.m_buttonId,params.m_userPointer);
|
MyButtonEventHandler* handler = new MyButtonEventHandler(button, params.m_callback,params.m_buttonId,params.m_userPointer);
|
||||||
button->SetText(params.m_name);
|
button->SetText(params.m_name);
|
||||||
button->onPress.Add( handler, &MyButtonEventHandler::onButtonPress );
|
button->onPress.Add( handler, &MyButtonEventHandler::onButtonPress );
|
||||||
button->SetIsToggle(params.m_isTrigger);
|
button->SetIsToggle(params.m_isTrigger);
|
||||||
|
button->SetToggleState(params.m_initialState);
|
||||||
|
|
||||||
m_paramInternalData->m_buttons.push_back(button);
|
m_paramInternalData->m_buttons.push_back(button);
|
||||||
m_paramInternalData->m_buttonEventHandlers.push_back(handler);
|
m_paramInternalData->m_buttonEventHandlers.push_back(handler);
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ class btCollisionShape;
|
|||||||
#include "BulletDynamics/Dynamics/btSimulationIslandManagerMt.h" // for setSplitIslands()
|
#include "BulletDynamics/Dynamics/btSimulationIslandManagerMt.h" // for setSplitIslands()
|
||||||
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.h"
|
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.h"
|
||||||
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
|
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
|
||||||
|
#include "BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.h"
|
||||||
|
#include "BulletDynamics/MLCPSolvers/btMLCPSolver.h"
|
||||||
|
#include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h"
|
||||||
|
#include "BulletDynamics/MLCPSolvers/btDantzigSolver.h"
|
||||||
|
#include "BulletDynamics/MLCPSolvers/btLemkeSolver.h"
|
||||||
|
|
||||||
TaskManager gTaskMgr;
|
TaskManager gTaskMgr;
|
||||||
|
|
||||||
@@ -46,6 +51,8 @@ TaskManager gTaskMgr;
|
|||||||
#define BT_OVERRIDE
|
#define BT_OVERRIDE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int gNumIslands = 0;
|
||||||
|
|
||||||
|
|
||||||
class Profiler
|
class Profiler
|
||||||
{
|
{
|
||||||
@@ -434,8 +441,6 @@ struct UpdateIslandDispatcher
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int gNumIslands = 0;
|
|
||||||
|
|
||||||
void parallelIslandDispatch( btAlignedObjectArray<btSimulationIslandManagerMt::Island*>* islandsPtr, btSimulationIslandManagerMt::IslandCallback* callback )
|
void parallelIslandDispatch( btAlignedObjectArray<btSimulationIslandManagerMt::Island*>* islandsPtr, btSimulationIslandManagerMt::IslandCallback* callback )
|
||||||
{
|
{
|
||||||
ProfileHelper prof(Profiler::kRecordDispatchIslands);
|
ProfileHelper prof(Profiler::kRecordDispatchIslands);
|
||||||
@@ -587,11 +592,47 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
btConstraintSolver* createSolverByType( SolverType t )
|
||||||
|
{
|
||||||
|
btMLCPSolverInterface* mlcpSolver = NULL;
|
||||||
|
switch ( t )
|
||||||
|
{
|
||||||
|
case SOLVER_TYPE_SEQUENTIAL_IMPULSE:
|
||||||
|
return new btSequentialImpulseConstraintSolver();
|
||||||
|
case SOLVER_TYPE_NNCG:
|
||||||
|
return new btNNCGConstraintSolver();
|
||||||
|
case SOLVER_TYPE_MLCP_PGS:
|
||||||
|
mlcpSolver = new btSolveProjectedGaussSeidel();
|
||||||
|
break;
|
||||||
|
case SOLVER_TYPE_MLCP_DANTZIG:
|
||||||
|
mlcpSolver = new btDantzigSolver();
|
||||||
|
break;
|
||||||
|
case SOLVER_TYPE_MLCP_LEMKE:
|
||||||
|
mlcpSolver = new btLemkeSolver();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mlcpSolver)
|
||||||
|
{
|
||||||
|
return new btMLCPSolver(mlcpSolver);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool gMultithreadedWorld = false;
|
static bool gMultithreadedWorld = false;
|
||||||
static bool gDisplayProfileInfo = false;
|
static bool gDisplayProfileInfo = false;
|
||||||
static btScalar gSliderNumThreads = 1.0f; // should be int
|
static SolverType gSolverType = SOLVER_TYPE_SEQUENTIAL_IMPULSE;
|
||||||
|
static int gSolverMode = SOLVER_SIMD |
|
||||||
|
SOLVER_USE_WARMSTARTING |
|
||||||
|
// SOLVER_RANDMIZE_ORDER |
|
||||||
|
// SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS |
|
||||||
|
// SOLVER_USE_2_FRICTION_DIRECTIONS |
|
||||||
|
0;
|
||||||
static btScalar gSliderSolverIterations = 10.0f; // should be int
|
static btScalar gSliderSolverIterations = 10.0f; // should be int
|
||||||
|
|
||||||
|
static btScalar gSliderNumThreads = 1.0f; // should be int
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
CommonRigidBodyMTBase::CommonRigidBodyMTBase( struct GUIHelperInterface* helper )
|
CommonRigidBodyMTBase::CommonRigidBodyMTBase( struct GUIHelperInterface* helper )
|
||||||
@@ -622,6 +663,33 @@ void boolPtrButtonCallback(int buttonId, bool buttonState, void* userPointer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toggleSolverModeCallback(int buttonId, bool buttonState, void* userPointer)
|
||||||
|
{
|
||||||
|
if (buttonState)
|
||||||
|
{
|
||||||
|
gSolverMode |= buttonId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gSolverMode &= ~buttonId;
|
||||||
|
}
|
||||||
|
if (CommonRigidBodyMTBase* crb = reinterpret_cast<CommonRigidBodyMTBase*>(userPointer))
|
||||||
|
{
|
||||||
|
if (crb->m_dynamicsWorld)
|
||||||
|
{
|
||||||
|
crb->m_dynamicsWorld->getSolverInfo().m_solverMode = gSolverMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSolverTypeCallback(int buttonId, bool buttonState, void* userPointer)
|
||||||
|
{
|
||||||
|
if (buttonId >= 0 && buttonId < SOLVER_TYPE_COUNT)
|
||||||
|
{
|
||||||
|
gSolverType = static_cast<SolverType>(buttonId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void apiSelectButtonCallback(int buttonId, bool buttonState, void* userPointer)
|
void apiSelectButtonCallback(int buttonId, bool buttonState, void* userPointer)
|
||||||
{
|
{
|
||||||
gTaskMgr.setApi(static_cast<TaskManager::Api>(buttonId));
|
gTaskMgr.setApi(static_cast<TaskManager::Api>(buttonId));
|
||||||
@@ -658,6 +726,7 @@ void setSolverIterationCountCallback(float val, void* userPtr)
|
|||||||
void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
|
void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
|
||||||
{
|
{
|
||||||
gNumIslands = 0;
|
gNumIslands = 0;
|
||||||
|
m_solverType = gSolverType;
|
||||||
#if BT_THREADSAFE && (BT_USE_OPENMP || BT_USE_PPL || BT_USE_TBB)
|
#if BT_THREADSAFE && (BT_USE_OPENMP || BT_USE_PPL || BT_USE_TBB)
|
||||||
m_multithreadCapable = true;
|
m_multithreadCapable = true;
|
||||||
#endif
|
#endif
|
||||||
@@ -677,10 +746,18 @@ void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
|
|||||||
|
|
||||||
m_broadphase = new btDbvtBroadphase();
|
m_broadphase = new btDbvtBroadphase();
|
||||||
|
|
||||||
#if USE_PARALLEL_ISLAND_SOLVER
|
#if BT_THREADSAFE && USE_PARALLEL_ISLAND_SOLVER
|
||||||
m_solver = new MyConstraintSolverPool( TaskManager::getMaxNumThreads() );
|
{
|
||||||
|
btConstraintSolver* solvers[ BT_MAX_THREAD_COUNT ];
|
||||||
|
int maxThreadCount = btMin( int(BT_MAX_THREAD_COUNT), TaskManager::getMaxNumThreads() );
|
||||||
|
for ( int i = 0; i < maxThreadCount; ++i )
|
||||||
|
{
|
||||||
|
solvers[ i ] = createSolverByType( m_solverType );
|
||||||
|
}
|
||||||
|
m_solver = new MyConstraintSolverPool( solvers, maxThreadCount );
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
m_solver = new btSequentialImpulseConstraintSolver();
|
m_solver = createSolverByType( m_solverType );
|
||||||
#endif //#if USE_PARALLEL_ISLAND_SOLVER
|
#endif //#if USE_PARALLEL_ISLAND_SOLVER
|
||||||
btDiscreteDynamicsWorld* world = new MyDiscreteDynamicsWorld( m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration );
|
btDiscreteDynamicsWorld* world = new MyDiscreteDynamicsWorld( m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration );
|
||||||
m_dynamicsWorld = world;
|
m_dynamicsWorld = world;
|
||||||
@@ -707,15 +784,14 @@ void CommonRigidBodyMTBase::createEmptyDynamicsWorld()
|
|||||||
|
|
||||||
m_broadphase = new btDbvtBroadphase();
|
m_broadphase = new btDbvtBroadphase();
|
||||||
|
|
||||||
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
|
m_solver = createSolverByType( m_solverType );
|
||||||
btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
|
|
||||||
m_solver = sol;
|
|
||||||
|
|
||||||
m_dynamicsWorld = new btDiscreteDynamicsWorld( m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration );
|
m_dynamicsWorld = new btDiscreteDynamicsWorld( m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration );
|
||||||
}
|
}
|
||||||
m_dynamicsWorld->setInternalTickCallback( profileBeginCallback, NULL, true );
|
m_dynamicsWorld->setInternalTickCallback( profileBeginCallback, NULL, true );
|
||||||
m_dynamicsWorld->setInternalTickCallback( profileEndCallback, NULL, false );
|
m_dynamicsWorld->setInternalTickCallback( profileEndCallback, NULL, false );
|
||||||
m_dynamicsWorld->setGravity( btVector3( 0, -10, 0 ) );
|
m_dynamicsWorld->setGravity( btVector3( 0, -10, 0 ) );
|
||||||
|
m_dynamicsWorld->getSolverInfo().m_solverMode = gSolverMode;
|
||||||
createDefaultParameters();
|
createDefaultParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,18 +802,33 @@ void CommonRigidBodyMTBase::createDefaultParameters()
|
|||||||
{
|
{
|
||||||
// create a button to toggle multithreaded world
|
// create a button to toggle multithreaded world
|
||||||
ButtonParams button( "Multithreaded world enable", 0, true );
|
ButtonParams button( "Multithreaded world enable", 0, true );
|
||||||
|
button.m_initialState = gMultithreadedWorld;
|
||||||
button.m_userPointer = &gMultithreadedWorld;
|
button.m_userPointer = &gMultithreadedWorld;
|
||||||
button.m_callback = boolPtrButtonCallback;
|
button.m_callback = boolPtrButtonCallback;
|
||||||
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// create a button to toggle profile printing
|
// create a button to toggle profile printing
|
||||||
ButtonParams button( "Display profile timings", 0, true );
|
ButtonParams button( "Display solver info", 0, true );
|
||||||
|
button.m_initialState = gDisplayProfileInfo;
|
||||||
button.m_userPointer = &gDisplayProfileInfo;
|
button.m_userPointer = &gDisplayProfileInfo;
|
||||||
button.m_callback = boolPtrButtonCallback;
|
button.m_callback = boolPtrButtonCallback;
|
||||||
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add buttons for switching to different solver types
|
||||||
|
for (int i = 0; i < SOLVER_TYPE_COUNT; ++i)
|
||||||
{
|
{
|
||||||
|
char buttonName[256];
|
||||||
|
SolverType solverType = static_cast<SolverType>(i);
|
||||||
|
sprintf(buttonName, "Solver Type %s", getSolverTypeName(solverType));
|
||||||
|
ButtonParams button( buttonName, 0, false );
|
||||||
|
button.m_buttonId = solverType;
|
||||||
|
button.m_callback = setSolverTypeCallback;
|
||||||
|
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// a slider for the number of solver iterations
|
||||||
SliderParams slider( "Solver iterations", &gSliderSolverIterations );
|
SliderParams slider( "Solver iterations", &gSliderSolverIterations );
|
||||||
slider.m_minVal = 1.0f;
|
slider.m_minVal = 1.0f;
|
||||||
slider.m_maxVal = 30.0f;
|
slider.m_maxVal = 30.0f;
|
||||||
@@ -746,6 +837,54 @@ void CommonRigidBodyMTBase::createDefaultParameters()
|
|||||||
slider.m_clampToIntegers = true;
|
slider.m_clampToIntegers = true;
|
||||||
m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider );
|
m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider );
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
ButtonParams button( "Solver use SIMD", 0, true );
|
||||||
|
button.m_buttonId = SOLVER_SIMD;
|
||||||
|
button.m_initialState = !! (gSolverMode & button.m_buttonId);
|
||||||
|
button.m_callback = toggleSolverModeCallback;
|
||||||
|
button.m_userPointer = this;
|
||||||
|
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ButtonParams button( "Solver randomize order", 0, true );
|
||||||
|
button.m_buttonId = SOLVER_RANDMIZE_ORDER;
|
||||||
|
button.m_initialState = !! (gSolverMode & button.m_buttonId);
|
||||||
|
button.m_callback = toggleSolverModeCallback;
|
||||||
|
button.m_userPointer = this;
|
||||||
|
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ButtonParams button( "Solver interleave contact/friction", 0, true );
|
||||||
|
button.m_buttonId = SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS;
|
||||||
|
button.m_initialState = !! (gSolverMode & button.m_buttonId);
|
||||||
|
button.m_callback = toggleSolverModeCallback;
|
||||||
|
button.m_userPointer = this;
|
||||||
|
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ButtonParams button( "Solver 2 friction directions", 0, true );
|
||||||
|
button.m_buttonId = SOLVER_USE_2_FRICTION_DIRECTIONS;
|
||||||
|
button.m_initialState = !! (gSolverMode & button.m_buttonId);
|
||||||
|
button.m_callback = toggleSolverModeCallback;
|
||||||
|
button.m_userPointer = this;
|
||||||
|
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ButtonParams button( "Solver friction dir caching", 0, true );
|
||||||
|
button.m_buttonId = SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;
|
||||||
|
button.m_initialState = !! (gSolverMode & button.m_buttonId);
|
||||||
|
button.m_callback = toggleSolverModeCallback;
|
||||||
|
button.m_userPointer = this;
|
||||||
|
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ButtonParams button( "Solver warmstarting", 0, true );
|
||||||
|
button.m_buttonId = SOLVER_USE_WARMSTARTING;
|
||||||
|
button.m_initialState = !! (gSolverMode & button.m_buttonId);
|
||||||
|
button.m_callback = toggleSolverModeCallback;
|
||||||
|
button.m_userPointer = this;
|
||||||
|
m_guiHelper->getParameterInterface()->registerButtonParameter( button );
|
||||||
|
}
|
||||||
if (m_multithreadedWorld)
|
if (m_multithreadedWorld)
|
||||||
{
|
{
|
||||||
// create a button for each supported threading API
|
// create a button for each supported threading API
|
||||||
@@ -781,6 +920,12 @@ void CommonRigidBodyMTBase::drawScreenText()
|
|||||||
int xCoord = 400;
|
int xCoord = 400;
|
||||||
int yCoord = 30;
|
int yCoord = 30;
|
||||||
int yStep = 30;
|
int yStep = 30;
|
||||||
|
if (m_solverType != gSolverType)
|
||||||
|
{
|
||||||
|
sprintf( msg, "restart example to change solver type" );
|
||||||
|
m_guiHelper->getAppInterface()->drawText( msg, 300, yCoord, 0.4f );
|
||||||
|
yCoord += yStep;
|
||||||
|
}
|
||||||
if (m_multithreadCapable)
|
if (m_multithreadCapable)
|
||||||
{
|
{
|
||||||
if ( m_multithreadedWorld != gMultithreadedWorld )
|
if ( m_multithreadedWorld != gMultithreadedWorld )
|
||||||
@@ -815,7 +960,20 @@ void CommonRigidBodyMTBase::drawScreenText()
|
|||||||
m_guiHelper->getAppInterface()->drawText( msg, 100, yCoord, 0.4f );
|
m_guiHelper->getAppInterface()->drawText( msg, 100, yCoord, 0.4f );
|
||||||
yCoord += yStep;
|
yCoord += yStep;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
int sm = gSolverMode;
|
||||||
|
sprintf( msg, "solver %s mode [%s%s%s%s%s%s]",
|
||||||
|
getSolverTypeName(m_solverType),
|
||||||
|
sm & SOLVER_SIMD ? "SIMD" : "",
|
||||||
|
sm & SOLVER_RANDMIZE_ORDER ? " randomize" : "",
|
||||||
|
sm & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS ? " interleave" : "",
|
||||||
|
sm & SOLVER_USE_2_FRICTION_DIRECTIONS ? " friction2x" : "",
|
||||||
|
sm & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING ? " frictionDirCaching" : "",
|
||||||
|
sm & SOLVER_USE_WARMSTARTING ? " warm" : ""
|
||||||
|
);
|
||||||
|
m_guiHelper->getAppInterface()->drawText( msg, xCoord, yCoord, 0.4f );
|
||||||
|
yCoord += yStep;
|
||||||
|
}
|
||||||
sprintf( msg, "internalSimStep %5.3f ms",
|
sprintf( msg, "internalSimStep %5.3f ms",
|
||||||
gProfiler.getAverageTime( Profiler::kRecordInternalTimeStep )*0.001f
|
gProfiler.getAverageTime( Profiler::kRecordInternalTimeStep )*0.001f
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,6 +11,31 @@
|
|||||||
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
|
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
|
||||||
#include "../CommonInterfaces/CommonWindowInterface.h"
|
#include "../CommonInterfaces/CommonWindowInterface.h"
|
||||||
|
|
||||||
|
enum SolverType
|
||||||
|
{
|
||||||
|
SOLVER_TYPE_SEQUENTIAL_IMPULSE,
|
||||||
|
SOLVER_TYPE_NNCG,
|
||||||
|
SOLVER_TYPE_MLCP_PGS,
|
||||||
|
SOLVER_TYPE_MLCP_DANTZIG,
|
||||||
|
SOLVER_TYPE_MLCP_LEMKE,
|
||||||
|
|
||||||
|
SOLVER_TYPE_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const char* getSolverTypeName( SolverType t )
|
||||||
|
{
|
||||||
|
switch (t)
|
||||||
|
{
|
||||||
|
case SOLVER_TYPE_SEQUENTIAL_IMPULSE: return "SequentialImpulse";
|
||||||
|
case SOLVER_TYPE_NNCG: return "NNCG";
|
||||||
|
case SOLVER_TYPE_MLCP_PGS: return "MLCP ProjectedGaussSeidel";
|
||||||
|
case SOLVER_TYPE_MLCP_DANTZIG: return "MLCP Dantzig";
|
||||||
|
case SOLVER_TYPE_MLCP_LEMKE: return "MLCP Lemke";
|
||||||
|
}
|
||||||
|
btAssert( !"unhandled solver type in switch" );
|
||||||
|
return "???";
|
||||||
|
}
|
||||||
|
|
||||||
struct CommonRigidBodyMTBase : public CommonExampleInterface
|
struct CommonRigidBodyMTBase : public CommonExampleInterface
|
||||||
{
|
{
|
||||||
//keep the collision shapes, for deletion/cleanup
|
//keep the collision shapes, for deletion/cleanup
|
||||||
@@ -20,6 +45,7 @@ struct CommonRigidBodyMTBase : public CommonExampleInterface
|
|||||||
btConstraintSolver* m_solver;
|
btConstraintSolver* m_solver;
|
||||||
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
||||||
btDiscreteDynamicsWorld* m_dynamicsWorld;
|
btDiscreteDynamicsWorld* m_dynamicsWorld;
|
||||||
|
SolverType m_solverType;
|
||||||
bool m_multithreadedWorld;
|
bool m_multithreadedWorld;
|
||||||
bool m_multithreadCapable;
|
bool m_multithreadCapable;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user