virtual void getAllContactManifolds(btManifoldArray& manifoldArray) See Demos/CharacterDemo/CharacterDemo.cpp for example usage of getAllContactManifolds Added btDbvtBroadphase to btBulletCollisionCommon.h headerfile Enable soft body vs concave (albeit slow) Improved contact point debug rendering (moved from constraint solver into debugDrawWorld)
313 lines
7.3 KiB
C++
313 lines
7.3 KiB
C++
/*
|
|
* 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 "DemoApplication.h"
|
|
#include "DemoEntries.h"
|
|
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
|
|
|
|
#include "GLDebugDrawer.h"
|
|
|
|
#include "LinearMath/btQuickprof.h"
|
|
|
|
|
|
|
|
namespace
|
|
{
|
|
int testIndex = 0;
|
|
int testSelection = 0;
|
|
btDemoEntry* entry;
|
|
DemoApplication* demo;
|
|
int iterationCount = 10;
|
|
int width = 640;
|
|
int height = 480;
|
|
int framePeriod = 16;//todo: test if this value should be 0
|
|
int mainWindow;
|
|
GLUI *glui;
|
|
float hz;
|
|
float viewZoom = 20.0f;
|
|
float viewX = 0.0f;
|
|
float viewY = 0.0f;
|
|
int tx, ty, tw, th;
|
|
int gDrawAabb=0;
|
|
int gWireFrame=0;
|
|
int gDebugContacts=0;
|
|
int gDebugNoDeactivation = 0;
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
/*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;
|
|
}
|
|
|
|
|
|
if (!demo->isIdle())
|
|
{
|
|
demo->clientMoveAndDisplay();
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
demo->displayCallback();
|
|
}
|
|
if (testSelection != testIndex)
|
|
{
|
|
testIndex = testSelection;
|
|
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);
|
|
}
|
|
}
|
|
|
|
void Keyboard(unsigned char key, int x, int y)
|
|
{
|
|
|
|
|
|
|
|
|
|
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);
|
|
break;
|
|
|
|
default:
|
|
if (demo)
|
|
{
|
|
demo->keyboardCallback(key,x,y);
|
|
}
|
|
}
|
|
}
|
|
|
|
void KeyboardSpecial(int key, int x, int y)
|
|
{
|
|
|
|
if (demo)
|
|
{
|
|
demo->specialKeyboard(key,x,y);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void Mouse(int button, int state, int x, int y)
|
|
{
|
|
if (demo)
|
|
demo->mouseFunc(button,state,x,y);
|
|
}
|
|
|
|
void MouseMotion(int x, int y)
|
|
{
|
|
demo->mouseMotionFunc(x,y);
|
|
}
|
|
|
|
#ifdef BT_USE_FREEGLUT
|
|
#include "GL/freeglut_ext.h"
|
|
#endif
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
|
|
|
|
|
|
int bulletVersion = btGetVersion();
|
|
printf("Bullet version %d\n",bulletVersion);
|
|
|
|
glutInit(&argc, argv);
|
|
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE |GLUT_DEPTH);
|
|
glutInitWindowSize(width, height);
|
|
mainWindow = glutCreateWindow("http://bulletphysics.com");
|
|
#ifdef BT_USE_FREEGLUT
|
|
glutSetOption (GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
|
|
#endif
|
|
entry = g_demoEntries + testIndex;
|
|
demo = CreatDemo(entry);
|
|
|
|
glutDisplayFunc(SimulationLoop);
|
|
GLUI_Master.set_glutReshapeFunc(Resize);
|
|
GLUI_Master.set_glutKeyboardFunc(Keyboard);
|
|
GLUI_Master.set_glutSpecialFunc(KeyboardSpecial);
|
|
GLUI_Master.set_glutMouseFunc(Mouse);
|
|
glutMotionFunc(MouseMotion);
|
|
|
|
|
|
glui = GLUI_Master.create_glui_subwindow( mainWindow,
|
|
GLUI_SUBWINDOW_RIGHT );
|
|
|
|
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, 100);
|
|
|
|
/* GLUI_Spinner* hertzSpinner =
|
|
glui->add_spinner("Hertz", GLUI_SPINNER_FLOAT, &hz);
|
|
hertzSpinner->set_float_limits(5.0f, 200.0f);
|
|
*/
|
|
|
|
// glui->add_checkbox("Position Correction", &settings.enablePositionCorrection);
|
|
// glui->add_checkbox("Warm Starting", &settings.enablePositionCorrection);
|
|
glui->add_checkbox("DisableDeactivation", &gDebugNoDeactivation);
|
|
|
|
glui->add_separator();
|
|
|
|
GLUI_Panel* drawPanel = glui->add_panel("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);
|
|
|
|
|
|
int testCount = 0;
|
|
btDemoEntry* e = g_demoEntries;
|
|
while (e->createFcn)
|
|
{
|
|
testList->add_item(testCount, e->name);
|
|
++testCount;
|
|
++e;
|
|
}
|
|
|
|
glui->add_button("Quit", 0,(GLUI_Update_CB)exit);
|
|
glui->set_main_gfx_window( mainWindow );
|
|
|
|
// Use a timer to control the frame rate.
|
|
glutTimerFunc(framePeriod, Timer, 0);
|
|
|
|
glutMainLoop();
|
|
|
|
return 0;
|
|
}
|