bullet3/Demos/AllBulletDemos/Main.cpp

436 lines
10 KiB
C++
Raw Normal View History

2007-10-18 06:37:36 +00:00
/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include <stdio.h>
#include "glui/GL/glui.h"
#include "LinearMath/btScalar.h"
#include "LinearMath/btMinMax.h"
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
#include "DemoApplication.h"
#include "DemoEntries.h"
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
#include "GLDebugDrawer.h"
#include "LinearMath/btQuickprof.h"
2007-10-18 06:37:36 +00:00
namespace
{
int testIndex=0;
int testSelection=0;
btDemoEntry* entry;
DemoApplication* demo;
int iterationCount;
int width;
int height;
int framePeriod;//todo: test if this value should be 0
2007-10-18 06:37:36 +00:00
int mainWindow;
GLUI *glui;
float hz;
float viewZoom=20.f;
float viewX;
float viewY;
2007-10-18 06:37:36 +00:00
int tx, ty, tw, th;
int gDrawAabb;
int gWireFrame;
int gDebugContacts;
int gDebugNoDeactivation;
int gUseWarmstarting;
int gRandomizeConstraints;
int gUseSplitImpulse;
float gErp;
float gSlop;
float gErp2;
float gWarmStartingParameter;
}
void setDefaultSettings()
{
viewX = 0.0f;
viewY = 0.0f;
framePeriod = 16;//todo: test if this value should be 0
width = 640;
height = 480;
iterationCount = 10;
gDrawAabb=0;
gWireFrame=0;
gDebugContacts=0;
gDebugNoDeactivation = 0;
gUseSplitImpulse = 0;
gUseWarmstarting = 1;
gRandomizeConstraints = 1;
gErp = 0.2f;
gSlop=0.0f;
gErp2 = 0.1f;
gWarmStartingParameter = 0.85f;
}
void setDefaultSettingsAndSync()
{
setDefaultSettings();
glui->sync_live();
}
void TogglePause()
{
if (demo)
demo->toggleIdle();
}
void ResetScene()
{
if (demo)
demo->clientResetScene();
}
void SingleSimulationStep()
{
if (demo)
demo->clientMoveAndDisplay();
2007-10-18 06:37:36 +00:00
}
2007-10-18 06:37:36 +00:00
void Resize(int w, int h)
{
width = w;
height = h;
GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th );
glViewport( tx, ty, tw, th );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (demo)
demo->reshape(tw, th);
2007-10-18 06:37:36 +00:00
}
DemoApplication* CreatDemo(btDemoEntry* entry)
{
DemoApplication* demo = entry->createFcn();
btAssert(demo);
if (demo->getDynamicsWorld())
{
demo->getDynamicsWorld()->setDebugDrawer(new GLDebugDrawer());
}
#ifndef BT_NO_PROFILE
CProfileManager::Reset();
#endif //BT_NO_PROFILE
return demo;
}
2007-10-18 06:37:36 +00:00
/*b2Vec2 ConvertScreenToWorld(int x, int y)
{
b2Vec2 p;
float ratio = float(tw) / float(th);
float u = x / float(tw);
float v = (th - y) / float(th);
p.x = viewZoom * (viewX - ratio) * (1.0f - u) + viewZoom * (ratio + viewX) * u;
p.y = viewZoom * (viewY - 0.1f) * (1.0f - v) + viewZoom * (viewY + 1.9f) * v;
return p;
}
*/
// This is used to control the frame rate (60Hz).
void Timer(int)
{
glutSetWindow(mainWindow);
glutPostRedisplay();
glutTimerFunc(framePeriod, Timer, 0);
}
void SimulationLoop()
{
if (gDrawAabb)
{
demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawAabb);
} else
{
demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawAabb));
}
if (gWireFrame)
{
demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawWireframe);
} else
{
demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawWireframe));
}
if (gDebugContacts)
{
demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_DrawContactPoints);
} else
{
demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_DrawContactPoints));
}
if (gDebugNoDeactivation)
{
demo->setDebugMode(demo->getDebugMode() |btIDebugDraw::DBG_NoDeactivation);
} else
{
demo->setDebugMode(demo->getDebugMode() & (~btIDebugDraw::DBG_NoDeactivation));
}
if (demo->getDynamicsWorld() && demo->getDynamicsWorld()->getWorldType() == BT_DISCRETE_DYNAMICS_WORLD)
{
btDiscreteDynamicsWorld* discreteWorld = (btDiscreteDynamicsWorld*) demo->getDynamicsWorld();
discreteWorld->getSolverInfo().m_numIterations = iterationCount;
discreteWorld->getSolverInfo().m_erp = gErp;
discreteWorld->getSolverInfo().m_erp2 = gErp2;
discreteWorld->getSolverInfo().m_linearSlop = gSlop;
discreteWorld->getSolverInfo().m_warmstartingFactor = gWarmStartingParameter;
discreteWorld->getSolverInfo().m_splitImpulse = gUseSplitImpulse;
btSequentialImpulseConstraintSolver* solver = ((btSequentialImpulseConstraintSolver*) discreteWorld->getConstraintSolver());
if (gUseWarmstarting)
{
discreteWorld->getSolverInfo().m_solverMode |= SOLVER_USE_WARMSTARTING;
} else
{
discreteWorld->getSolverInfo().m_solverMode &= (~SOLVER_USE_WARMSTARTING);
}
if (gRandomizeConstraints)
{
discreteWorld->getSolverInfo().m_solverMode |= SOLVER_RANDMIZE_ORDER;
} else
{
discreteWorld->getSolverInfo().m_solverMode &= (~SOLVER_RANDMIZE_ORDER);
}
}
if (!demo->isIdle())
{
demo->clientMoveAndDisplay();
}
else
{
demo->displayCallback();
}
2007-10-18 06:37:36 +00:00
if (testSelection != testIndex)
{
testIndex = testSelection;
if (demo->getDynamicsWorld() && demo->getDynamicsWorld()->getDebugDrawer())
delete demo->getDynamicsWorld()->getDebugDrawer();
delete demo;
entry = g_demoEntries + testIndex;
demo = CreatDemo(entry);
2007-10-18 06:37:36 +00:00
viewZoom = 20.0f;
viewX = 0.0f;
viewY = 0.0f;
Resize(width, height);
}
}
2007-10-18 06:37:36 +00:00
void RestartScene()
{
if (demo->getDynamicsWorld() && demo->getDynamicsWorld()->getDebugDrawer())
delete demo->getDynamicsWorld()->getDebugDrawer();
delete demo;
entry = g_demoEntries + testIndex;
demo = CreatDemo(entry);
viewZoom = 20.0f;
viewX = 0.0f;
viewY = 0.0f;
Resize(width, height);
}
2007-10-18 06:37:36 +00:00
void Keyboard(unsigned char key, int x, int y)
{
2007-10-18 06:37:36 +00:00
switch (key)
{
case 27:
exit(0);
break;
// Press 'r' to reset.
case 'r':
if (demo->getDynamicsWorld()->getDebugDrawer())
delete demo->getDynamicsWorld()->getDebugDrawer();
delete demo;
demo = CreatDemo(entry);
Resize(width,height);
2007-10-18 06:37:36 +00:00
break;
default:
if (demo)
2007-10-18 06:37:36 +00:00
{
demo->keyboardCallback(key,x,y);
2007-10-18 06:37:36 +00:00
}
}
}
void KeyboardSpecial(int key, int x, int y)
{
if (demo)
2007-10-18 06:37:36 +00:00
{
demo->specialKeyboard(key,x,y);
2007-10-18 06:37:36 +00:00
}
2007-10-18 06:37:36 +00:00
}
2007-10-18 06:37:36 +00:00
void Mouse(int button, int state, int x, int y)
{
if (demo)
demo->mouseFunc(button,state,x,y);
2007-10-18 06:37:36 +00:00
}
void MouseMotion(int x, int y)
{
demo->mouseMotionFunc(x,y);
2007-10-18 06:37:36 +00:00
}
#ifdef BT_USE_FREEGLUT
2007-12-14 02:48:53 +00:00
#include "GL/freeglut_ext.h"
#endif
2007-10-18 06:37:36 +00:00
int main(int argc, char** argv)
{
setDefaultSettings();
int bulletVersion = btGetVersion();
printf("Bullet version %d\n",bulletVersion);
2007-10-18 06:37:36 +00:00
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE |GLUT_DEPTH | GLUT_STENCIL);
2007-10-18 06:37:36 +00:00
glutInitWindowSize(width, height);
mainWindow = glutCreateWindow("http://bulletphysics.com");
#ifdef BT_USE_FREEGLUT
2007-12-14 02:48:53 +00:00
glutSetOption (GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
#endif
entry = g_demoEntries + testIndex;
demo = CreatDemo(entry);
2007-10-18 06:37:36 +00:00
glutDisplayFunc(SimulationLoop);
GLUI_Master.set_glutReshapeFunc(Resize);
GLUI_Master.set_glutKeyboardFunc(Keyboard);
GLUI_Master.set_glutSpecialFunc(KeyboardSpecial);
GLUI_Master.set_glutMouseFunc(Mouse);
glutMotionFunc(MouseMotion);
2007-10-23 05:46:16 +00:00
2007-10-18 06:37:36 +00:00
glui = GLUI_Master.create_glui_subwindow( mainWindow,
GLUI_SUBWINDOW_RIGHT );
2007-10-18 06:37:36 +00:00
glui->add_statictext("Tests");
GLUI_Listbox* testList =
glui->add_listbox("", &testSelection);
glui->add_separator();
GLUI_Spinner* iterationSpinner =
glui->add_spinner("Iterations", GLUI_SPINNER_INT, &iterationCount);
iterationSpinner->set_int_limits(1, 250);
2007-10-18 06:37:36 +00:00
/* GLUI_Spinner* hertzSpinner =
glui->add_spinner("Hertz", GLUI_SPINNER_FLOAT, &hz);
2007-10-18 06:37:36 +00:00
hertzSpinner->set_float_limits(5.0f, 200.0f);
*/
2007-10-18 06:37:36 +00:00
glui->add_checkbox("DisableDeactivation", &gDebugNoDeactivation);
glui->add_checkbox("Split Impulse", &gUseSplitImpulse);
GLUI_Spinner* spinner = 0;
spinner = glui->add_spinner("ERP", GLUI_SPINNER_FLOAT, &gErp);
spinner->set_float_limits(0.f,1.f);
spinner = glui->add_spinner("ERP2", GLUI_SPINNER_FLOAT, &gErp2);
spinner->set_float_limits(0.f,1.f);
spinner = glui->add_spinner("Slop", GLUI_SPINNER_FLOAT, &gSlop);
spinner->set_float_limits(0.f,1.f);
spinner = glui->add_spinner("WSP", GLUI_SPINNER_FLOAT,&gWarmStartingParameter);
spinner->set_float_limits (0.f,1.0);
glui->add_checkbox("Warmstarting", &gUseWarmstarting);
glui->add_checkbox("Randomize Constraints", &gRandomizeConstraints);
2007-10-18 06:37:36 +00:00
glui->add_button("Reset Defaults", 0,(GLUI_Update_CB)setDefaultSettingsAndSync);
2007-10-18 06:37:36 +00:00
glui->add_separator();
GLUI_Panel* drawPanel = glui->add_panel("Debug Draw");
glui->add_checkbox_to_panel(drawPanel, "AABBs", &gDrawAabb);
glui->add_checkbox_to_panel(drawPanel, "Wireframe", &gWireFrame);
glui->add_checkbox_to_panel(drawPanel, "Contacts", &gDebugContacts);
// glui->add_checkbox_to_panel(drawPanel, "Impulses", &settings.drawImpulses);
// glui->add_checkbox_to_panel(drawPanel, "Statistics", &settings.drawStats);
2007-10-18 06:37:36 +00:00
2007-10-18 06:37:36 +00:00
int testCount = 0;
btDemoEntry* e = g_demoEntries;
2007-10-18 06:37:36 +00:00
while (e->createFcn)
{
testList->add_item(testCount, e->name);
++testCount;
++e;
}
glui->add_separator();
glui->add_button("Toggle Pause", 0,(GLUI_Update_CB)TogglePause);
glui->add_button("Single Step", 0,(GLUI_Update_CB)SingleSimulationStep);
glui->add_button("Reset Scene", 0,(GLUI_Update_CB)ResetScene);
glui->add_button("Restart Scene", 0,(GLUI_Update_CB)RestartScene);
glui->add_separator();
glui->add_button("Exit", 0,(GLUI_Update_CB)exit);
2007-10-18 06:37:36 +00:00
glui->set_main_gfx_window( mainWindow );
// Use a timer to control the frame rate.
glutTimerFunc(framePeriod, Timer, 0);
glutMainLoop();
return 0;
}