Created basic physics-based OpenGL menu dialog system, with toggle/text and slider control.

This commit is contained in:
erwin.coumans
2009-09-26 01:44:09 +00:00
parent a482ebb7ab
commit 2f4f468f4d
10 changed files with 1690 additions and 125 deletions

View File

@@ -17,8 +17,11 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h"
#include "GL_DialogDynamicsWorld.h"
#include "GL_DialogWindow.h"
#include "BulletCollision/CollisionShapes/btBox2dShape.h"
#include "BulletCollision/CollisionShapes/btConvex2dShape.h"
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
@@ -61,6 +64,9 @@ void Box2dDemo::clientMoveAndDisplay()
renderme();
if (m_dialogDynamicsWorld)
m_dialogDynamicsWorld->draw(ms / 1000000.f);
glFlush();
glutSwapBuffers();
@@ -79,21 +85,62 @@ void Box2dDemo::displayCallback(void) {
if (m_dynamicsWorld)
m_dynamicsWorld->debugDrawWorld();
if (m_dialogDynamicsWorld)
m_dialogDynamicsWorld->draw(0.f);
glFlush();
glutSwapBuffers();
}
void Box2dDemo::reshape(int w, int h)
{
if (m_dialogDynamicsWorld)
m_dialogDynamicsWorld->setScreenSize(w,h);
GlutDemoApplication::reshape(w,h);
}
void Box2dDemo::initPhysics()
{
m_dialogDynamicsWorld = new GL_DialogDynamicsWorld();
//m_dialogDynamicsWorld->createDialog(100,110,200,50);
//m_dialogDynamicsWorld->createDialog(100,00,100,100);
//m_dialogDynamicsWorld->createDialog(0,0,100,100);
GL_DialogWindow* settings = m_dialogDynamicsWorld->createDialog(50,0,200,120,"Settings");
GL_ToggleControl* toggle = m_dialogDynamicsWorld->createToggle(settings,"Toggle 1");
toggle = m_dialogDynamicsWorld->createToggle(settings,"Toggle 2");
toggle ->m_active = true;
toggle = m_dialogDynamicsWorld->createToggle(settings,"Toggle 3");
GL_SliderControl* slider = m_dialogDynamicsWorld->createSlider(settings,"Slider");
GL_DialogWindow* dialog = m_dialogDynamicsWorld->createDialog(0,200,420,300,"Help");
GL_TextControl* txt = new GL_TextControl;
dialog->addControl(txt);
txt->m_textLines.push_back("Mouse to move");
txt->m_textLines.push_back("Test 2");
txt->m_textLines.push_back("mouse to interact");
txt->m_textLines.push_back("ALT + mouse to move camera");
txt->m_textLines.push_back("space to reset");
txt->m_textLines.push_back("cursor keys and z,x to navigate");
txt->m_textLines.push_back("i to toggle simulation, s single step");
txt->m_textLines.push_back("q to quit");
txt->m_textLines.push_back(". to shoot box");
txt->m_textLines.push_back("d to toggle deactivation");
txt->m_textLines.push_back("g to toggle mesh animation (ConcaveDemo)");
txt->m_textLines.push_back("h to toggle help text");
txt->m_textLines.push_back("o to toggle orthogonal/perspective view");
//txt->m_textLines.push_back("+- shooting speed = %10.2f",m_ShootBoxInitialSpeed);
setTexturing(true);
setShadows(true);
setCameraDistance(btScalar(SCALING*50.));
m_cameraTargetPosition.setValue(0, ARRAY_SIZE_Y, 0);
m_cameraTargetPosition.setValue(0,0,0);//0, ARRAY_SIZE_Y, 0);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btDefaultCollisionConfiguration();
@@ -255,6 +302,8 @@ void Box2dDemo::initPhysics()
void Box2dDemo::exitPhysics()
{
delete m_dialogDynamicsWorld;
m_dialogDynamicsWorld = 0;
//cleanup in the reverse order of creation/initialization
@@ -292,6 +341,18 @@ void Box2dDemo::exitPhysics()
}
void Box2dDemo::mouseFunc(int button, int state, int x, int y)
{
if (!m_dialogDynamicsWorld->mouseFunc(button,state,x,y))
{
DemoApplication::mouseFunc(button,state,x,y);
}
}
void Box2dDemo::mouseMotionFunc(int x,int y)
{
m_dialogDynamicsWorld->mouseMotionFunc(x,y);
DemoApplication::mouseMotionFunc(x,y);
}

View File

@@ -25,6 +25,7 @@ class btCollisionDispatcher;
class btConstraintSolver;
struct btCollisionAlgorithmCreateFunc;
class btDefaultCollisionConfiguration;
class GL_DialogDynamicsWorld;
///Box2dDemo is good starting point for learning the code base and porting.
class Box2dDemo : public GlutDemoApplication
@@ -41,15 +42,20 @@ class Box2dDemo : public GlutDemoApplication
btDefaultCollisionConfiguration* m_collisionConfiguration;
GL_DialogDynamicsWorld* m_dialogDynamicsWorld;
public:
Box2dDemo()
Box2dDemo() : m_dialogDynamicsWorld(0)
{
}
virtual ~Box2dDemo()
{
exitPhysics();
}
virtual void reshape(int w, int h);
void initPhysics();
void exitPhysics();
@@ -66,6 +72,9 @@ class Box2dDemo : public GlutDemoApplication
return demo;
}
virtual void mouseFunc(int button, int state, int x, int y);
virtual void mouseMotionFunc(int x,int y);
};

View File

@@ -1211,125 +1211,7 @@ void DemoApplication::renderme()
#endif //USE_QUICKPROF
sprintf(buf,"mouse to interact");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"ALT + mouse to move camera");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"space to reset");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"cursor keys and z,x to navigate");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"i to toggle simulation, s single step");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"q to quit");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,". to shoot box");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
// not yet hooked up again after refactoring...
sprintf(buf,"d to toggle deactivation");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"g to toggle mesh animation (ConcaveDemo)");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"h to toggle help text");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"o to toggle orthogonal/perspective view");
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
//bool useBulletLCP = !(getDebugMode() & btIDebugDraw::DBG_DisableBulletLCP);
//bool useCCD = (getDebugMode() & btIDebugDraw::DBG_EnableCCD);
//glRasterPos3f(xOffset,yStart,0);
//sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD);
//GLDebugDrawString(BMF_GetFont(BMF_kHelvetica10),buf);
//yStart += yIncr;
sprintf(buf,"+- shooting speed = %10.2f",m_ShootBoxInitialSpeed);
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
#ifdef SHOW_NUM_DEEP_PENETRATIONS
sprintf(buf,"gNumDeepPenetrationChecks = %d",gNumDeepPenetrationChecks);
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"gNumGjkChecks= %d",gNumGjkChecks);
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"gNumClampedCcdMotions = %d",gNumClampedCcdMotions);
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"gNumSplitImpulseRecoveries= %d",gNumSplitImpulseRecoveries);
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"gNumAlignedAllocs = %d",gNumAlignedAllocs);
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"gNumAlignedFree= %d",gNumAlignedFree);
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"# alloc-free = %d",gNumAlignedAllocs-gNumAlignedFree);
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
//enable BT_DEBUG_MEMORY_ALLOCATIONS define in Bullet/src/LinearMath/btAlignedAllocator.h for memory leak detection
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
glRasterPos3f(xOffset,yStart,0);
sprintf(buf,"gTotalBytesAlignedAllocs = %d",gTotalBytesAlignedAllocs);
GLDebugDrawString(BMF_GetFont(BMF_kHelvetica10),buf);
yStart += yIncr;
#endif //BT_DEBUG_MEMORY_ALLOCATIONS
if (getDynamicsWorld())
{
glRasterPos3f(xOffset,yStart,0);
sprintf(buf,"# objects = %d",getDynamicsWorld()->getNumCollisionObjects());
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
glRasterPos3f(xOffset,yStart,0);
sprintf(buf,"# pairs = %d",getDynamicsWorld()->getBroadphase()->getOverlappingPairCache()->getNumOverlappingPairs());
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
sprintf(buf,"# hitPos = %f,%f,%f",gHitPos.getX(),gHitPos.getY(),gHitPos.getZ());
GLDebugDrawString(xOffset,yStart,buf);
yStart += yIncr;
}
#endif //SHOW_NUM_DEEP_PENETRATIONS
resetPerspectiveProjection();
}

View File

@@ -48,9 +48,9 @@ void GLDebugResetFont(int screenWidth,int screenHeight)
}
void GLDebugDrawString(int x,int y,const char* string)
{
void GLDebugDrawStringInternal(int x,int y,const char* string, const btVector3& rgb)
{
const char* string2 = "test";
if (sTexture==-1)
{
@@ -59,7 +59,7 @@ void GLDebugDrawString(int x,int y,const char* string)
if (strlen(string))
{
glColor3f(1.,1.,1.);
glColor3f(rgb.getX(),rgb.getY(),rgb.getZ());
float cx;
float cy;
@@ -128,6 +128,13 @@ void GLDebugDrawString(int x,int y,const char* string)
}
}
void GLDebugDrawString(int x,int y,const char* string)
{
btVector3 rgb(1,1,1);
GLDebugDrawStringInternal(x,y,string,rgb);
}
unsigned char sFontData[] =
{

View File

@@ -17,6 +17,9 @@ subject to the following restrictions:
#ifndef BT_DEBUG_FONT_H
#define BT_DEBUG_FONT_H
#include "LinearMath/btVector3.h"
void GLDebugDrawStringInternal(int x,int y,const char* string,const btVector3& rgb);
void GLDebugDrawString(int x,int y,const char* string);
void GLDebugResetFont(int screenWidth,int screenHeight);

View File

@@ -0,0 +1,736 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
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 "GL_DialogDynamicsWorld.h"
#include "GL_DialogWindow.h"
#include "btBulletDynamicsCommon.h"
#include "BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h"
#include "BulletCollision/CollisionShapes/btBox2dShape.h"
#include "BulletCollision/CollisionShapes/btConvex2dShape.h"
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
GL_DialogDynamicsWorld::GL_DialogDynamicsWorld()
{
m_upperBorder = 0;
m_lowerBorder =0;
m_pickConstraint = 0;
m_screenWidth = 0;
m_screenHeight = 0;
m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_broadphase = new btDbvtBroadphase();
m_constraintSolver = new btSequentialImpulseConstraintSolver();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_constraintSolver,m_collisionConfiguration);
m_dynamicsWorld ->getSolverInfo().m_splitImpulse = true;
//m_dynamicsWorld->setGravity(btVector3(0,10,0));
m_dynamicsWorld->setGravity(btVector3(0,0,0));
m_simplexSolver = new btVoronoiSimplexSolver();
m_pdSolver = new btMinkowskiPenetrationDepthSolver();
btConvex2dConvex2dAlgorithm::CreateFunc* convexAlgo2d = new btConvex2dConvex2dAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver);
m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d);
m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,CONVEX_2D_SHAPE_PROXYTYPE,convexAlgo2d);
m_dispatcher->registerCollisionCreateFunc(CONVEX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,convexAlgo2d);
m_dispatcher->registerCollisionCreateFunc(BOX_2D_SHAPE_PROXYTYPE,BOX_2D_SHAPE_PROXYTYPE,new btBox2dBox2dCollisionAlgorithm::CreateFunc());
///enable boarders, to avoid 'loosing' menus
#if 1
btTransform tr;
tr.setIdentity();
{
btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(0,1,0),0);
m_upperBorder = new btCollisionObject();
tr.setOrigin(btVector3(0,-BT_LARGE_FLOAT,0));
m_upperBorder->setWorldTransform(tr);
m_upperBorder->setCollisionShape(plane);
m_dynamicsWorld->addCollisionObject(m_upperBorder);
}
{
btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(0,-1,0),0);
m_lowerBorder = new btCollisionObject();
tr.setIdentity();
tr.setOrigin(btVector3(0,BT_LARGE_FLOAT,0));
m_lowerBorder->setWorldTransform(tr);
m_lowerBorder->setCollisionShape(plane);
m_dynamicsWorld->addCollisionObject(m_lowerBorder);
}
{
btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(1,0,0),0);
m_leftBorder = new btCollisionObject();
tr.setIdentity();
tr.setOrigin(btVector3(-BT_LARGE_FLOAT,0,0));
m_leftBorder->setWorldTransform(tr);
m_leftBorder->setCollisionShape(plane);
m_dynamicsWorld->addCollisionObject(m_leftBorder);
}
{
btStaticPlaneShape* plane = new btStaticPlaneShape(btVector3(-1,0,0),0);
m_rightBorder = new btCollisionObject();
tr.setIdentity();
tr.setOrigin(btVector3(BT_LARGE_FLOAT,0,0));
m_rightBorder->setWorldTransform(tr);
m_rightBorder->setCollisionShape(plane);
m_dynamicsWorld->addCollisionObject(m_rightBorder);
}
#endif
}
GL_DialogDynamicsWorld::~GL_DialogDynamicsWorld()
{
delete m_dynamicsWorld;
delete m_dispatcher;
delete m_constraintSolver;
delete m_broadphase;
delete m_collisionConfiguration;
}
void GL_DialogDynamicsWorld::setScreenSize(int width, int height)
{
for (int i=0;i<m_dynamicsWorld->getCollisionObjectArray().size();i++)
{
btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
m_dynamicsWorld->removeRigidBody(body);
btVector3 newPos = colObj->getWorldTransform().getOrigin() + btVector3(m_screenWidth/2,m_screenHeight/2,0)-btVector3(width/2,height/2,0);
colObj->getWorldTransform().setOrigin(newPos);
m_dynamicsWorld->addRigidBody(body);
} else
{
m_dynamicsWorld->removeCollisionObject(colObj);
btVector3 newPos = colObj->getWorldTransform().getOrigin() + btVector3(m_screenWidth/2,m_screenHeight/2,0)-btVector3(width/2,height/2,0);
colObj->getWorldTransform().setOrigin(newPos);
m_dynamicsWorld->addCollisionObject(colObj);
}
}
for (int i=0;i<m_dialogs.size();i++)
{
m_dialogs[i]->setScreenSize(width,height);
}
if (width && height)
{
if (m_upperBorder)
{
m_dynamicsWorld->removeCollisionObject(m_upperBorder);
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0,-height/2,0));
m_upperBorder->setWorldTransform(tr);
m_dynamicsWorld->addCollisionObject(m_upperBorder);
}
if (m_lowerBorder)
{
m_dynamicsWorld->removeCollisionObject(m_lowerBorder);
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0,height/2,0));
m_lowerBorder->setWorldTransform(tr);
m_dynamicsWorld->addCollisionObject(m_lowerBorder);
}
if (m_leftBorder)
{
m_dynamicsWorld->removeCollisionObject(m_leftBorder);
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(-width/2,0,0));
m_leftBorder->setWorldTransform(tr);
m_dynamicsWorld->addCollisionObject(m_leftBorder);
}
if (m_rightBorder)
{
m_dynamicsWorld->removeCollisionObject(m_rightBorder);
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(width/2,0,0));
m_rightBorder->setWorldTransform(tr);
m_dynamicsWorld->addCollisionObject(m_rightBorder);
}
}
m_screenWidth = width;
m_screenHeight = height;
}
GL_DialogWindow* GL_DialogDynamicsWorld::createDialog(int horPos,int vertPos,int dialogWidth,int dialogHeight, const char* dialogTitle )
{
btBox2dShape* boxShape = new btBox2dShape(btVector3(dialogWidth/2.,dialogHeight/2.,0.4));
btScalar mass = 100.f;
btVector3 localInertia;
boxShape->calculateLocalInertia(mass,localInertia);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,boxShape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
btTransform trans;
trans.setIdentity();
trans.setOrigin(btVector3(horPos-m_screenWidth/2+dialogWidth/2, vertPos+m_screenHeight/2.+dialogHeight/2,0.));
body->setWorldTransform(trans);
body->setDamping(0.999,0.99);
//body->setContactProcessingThreshold(colShape->getContactBreakingThreshold());
//body->setActivationState(ISLAND_SLEEPING);
body->setLinearFactor(btVector3(1,1,0));
//body->setAngularFactor(btVector3(0,0,1));
body->setAngularFactor(btVector3(0,0,0));
GL_DialogWindow* dialogWindow = new GL_DialogWindow(horPos,vertPos,dialogWidth,dialogHeight,body,dialogTitle);
m_dialogs.push_back(dialogWindow);
m_dynamicsWorld->addRigidBody(body);
return dialogWindow;
}
GL_SliderControl* GL_DialogDynamicsWorld::createSlider(GL_DialogWindow* dialog, const char* sliderText)
{
btBox2dShape* boxShape = new btBox2dShape(btVector3(6,6,0.4));
btScalar mass = .1f;
btVector3 localInertia;
boxShape->calculateLocalInertia(mass,localInertia);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,boxShape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
btTransform trans;
trans.setIdentity();
trans.setOrigin(btVector3(dialog->getDialogHorPos()-m_screenWidth/2+dialog->getDialogWidth()/2, dialog->getDialogVertPos()+m_screenHeight/2.+dialog->getDialogHeight()/2+dialog->getNumControls()*20,-0.2));
body->setWorldTransform(trans);
//body->setDamping(0.999,0.99);
//body->setContactProcessingThreshold(colShape->getContactBreakingThreshold());
//body->setActivationState(ISLAND_SLEEPING);
body->setLinearFactor(btVector3(1,1,0));
//body->setAngularFactor(btVector3(0,0,1));
body->setAngularFactor(btVector3(0,0,0));
m_dynamicsWorld->addRigidBody(body);
btRigidBody* dialogBody = btRigidBody::upcast(dialog->getCollisionObject());
btAssert(dialogBody);
btTransform frameInA;
frameInA.setIdentity();
btVector3 offset(btVector3(-dialog->getDialogWidth()/2+16,-dialog->getDialogHeight()/2+dialog->getNumControls()*20+36,0.2));
frameInA.setOrigin(offset);
btTransform frameInB;
frameInB.setIdentity();
//frameInB.setOrigin(-offset/2);
bool useFrameA = false;
btScalar lowerLimit = 80;
btScalar upperLimit = 170;
#if 0
btGeneric6DofConstraint* constraint = new btGeneric6DofConstraint(*dialogBody,*body,frameInA,frameInB,useFrameA);
m_dynamicsWorld->addConstraint(constraint,true);
constraint->setLimit(0,lowerLimit,upperLimit);
#else
btSliderConstraint* sliderConstraint = new btSliderConstraint(*dialogBody,*body,frameInA,frameInB,true);//useFrameA);
sliderConstraint->setLowerLinLimit(lowerLimit);
sliderConstraint->setUpperLinLimit(upperLimit);
m_dynamicsWorld->addConstraint(sliderConstraint,true);
#endif
GL_SliderControl* slider = new GL_SliderControl(sliderText, body,dialog,lowerLimit,upperLimit, sliderConstraint);
body->setUserPointer(slider);
dialog->addControl(slider);
return slider;
}
GL_ToggleControl* GL_DialogDynamicsWorld::createToggle(GL_DialogWindow* dialog, const char* toggleText)
{
btBox2dShape* boxShape = new btBox2dShape(btVector3(6,6,0.4));
btScalar mass = 0.1f;
btVector3 localInertia;
boxShape->calculateLocalInertia(mass,localInertia);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,boxShape,localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
btTransform trans;
trans.setIdentity();
trans.setOrigin(btVector3(dialog->getDialogHorPos()-m_screenWidth/2+dialog->getDialogWidth()/2, dialog->getDialogVertPos()+m_screenHeight/2.+dialog->getDialogHeight()/2+dialog->getNumControls()*20,-0.2));
body->setWorldTransform(trans);
body->setDamping(0.999,0.99);
//body->setContactProcessingThreshold(colShape->getContactBreakingThreshold());
//body->setActivationState(ISLAND_SLEEPING);
body->setLinearFactor(btVector3(1,1,0));
//body->setAngularFactor(btVector3(0,0,1));
body->setAngularFactor(btVector3(0,0,0));
m_dynamicsWorld->addRigidBody(body);
btRigidBody* dialogBody = btRigidBody::upcast(dialog->getCollisionObject());
btAssert(dialogBody);
btTransform frameInA;
frameInA.setIdentity();
btVector3 offset(btVector3(+dialog->getDialogWidth()/2-32,-dialog->getDialogHeight()/2+dialog->getNumControls()*20+36,0.2));
frameInA.setOrigin(offset);
btTransform frameInB;
frameInB.setIdentity();
//frameInB.setOrigin(-offset/2);
bool useFrameA = true;
btGeneric6DofConstraint* constraint = new btGeneric6DofConstraint(*dialogBody,*body,frameInA,frameInB,useFrameA);
m_dynamicsWorld->addConstraint(constraint,true);
GL_ToggleControl* toggle = new GL_ToggleControl(toggleText, body,dialog);
body->setUserPointer(toggle);
dialog->addControl(toggle);
return toggle;
}
void GL_DialogDynamicsWorld::draw(btScalar timeStep)
{
if (timeStep)
{
m_dynamicsWorld->stepSimulation(timeStep);
}
for (int i=0;i<m_dialogs.size();i++)
{
m_dialogs[i]->draw(timeStep);
}
}
static btRigidBody* pickedBody = 0;//for deactivation state
static btScalar mousePickClamping = 111130.f;
static int gPickingConstraintId = 0;
static btVector3 gOldPickingPos;
static btVector3 gHitPos(-1,-1,-1);
static float gOldPickingDist = 0.f;
bool GL_DialogDynamicsWorld::mouseFunc(int button, int state, int x, int y)
{
if (state == 0)
{
m_mouseButtons |= 1<<button;
} else
{
m_mouseButtons = 0;
}
m_mouseOldX = x;
m_mouseOldY = y;
//printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y);
//button 0, state 0 means left mouse down
btVector3 rayTo = getRayTo(x,y);
switch (button)
{
case 1:
{
if (state==0)
{
#if 0
//apply an impulse
if (m_dynamicsWorld)
{
btCollisionWorld::ClosestRayResultCallback rayCallback(m_cameraPosition,rayTo);
m_dynamicsWorld->rayTest(m_cameraPosition,rayTo,rayCallback);
if (rayCallback.hasHit())
{
btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
if (body)
{
body->setActivationState(ACTIVE_TAG);
btVector3 impulse = rayTo;
impulse.normalize();
float impulseStrength = 10.f;
impulse *= impulseStrength;
btVector3 relPos = rayCallback.m_hitPointWorld - body->getCenterOfMassPosition();
body->applyImpulse(impulse,relPos);
}
}
}
#endif
} else
{
}
break;
}
case 0:
{
if (state==0)
{
//add a point to point constraint for picking
if (m_dynamicsWorld)
{
btVector3 rayFrom;
if (1)//m_ortho)
{
rayFrom = rayTo;
rayFrom.setZ(-100.f);
}
//else
//{
// rayFrom = m_cameraPosition;
//}
btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback);
if (rayCallback.hasHit())
{
btScalar maxPickingClamp = mousePickClamping;
btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
if (body)
{
bool doPick = true;
if (body->getUserPointer())
{
///deal with controls in a special way
GL_DialogControl* ctrl = (GL_DialogControl*)body->getUserPointer();
switch(ctrl->getType())
{
case GL_TOGGLE_CONTROL:
{
GL_ToggleControl* toggle = (GL_ToggleControl*) ctrl;
toggle->m_active = !toggle->m_active;
doPick = false;
break;
}
case GL_SLIDER_CONTROL:
{
GL_SliderControl* slider = (GL_SliderControl*) ctrl;
btTypedConstraint* constraint = slider->getConstraint();
if (constraint->getConstraintType() == SLIDER_CONSTRAINT_TYPE)
{
btSliderConstraint* sliderConstraint = (btSliderConstraint*) constraint;
sliderConstraint->setLowerLinLimit(slider->getLowerLimit());
sliderConstraint->setUpperLinLimit(slider->getUpperLimit());
}
maxPickingClamp = 100;
}
default:
{
}
};
};
if (doPick)
{
//other exclusions?
if (!(body->isStaticObject() || body->isKinematicObject()))
{
pickedBody = body;
pickedBody->setActivationState(DISABLE_DEACTIVATION);
btVector3 pickPos = rayCallback.m_hitPointWorld;
//printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ());
btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos;
btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,localPivot);
p2p->m_setting.m_impulseClamp = maxPickingClamp;
m_dynamicsWorld->addConstraint(p2p);
m_pickConstraint = p2p;
//save mouse position for dragging
gOldPickingPos = rayTo;
gHitPos = pickPos;
gOldPickingDist = (pickPos-rayFrom).length();
//very weak constraint for picking
p2p->m_setting.m_tau = 0.1f;
}
}
return true;
}
}
}
} else
{
if (m_pickConstraint && m_dynamicsWorld)
{
m_dynamicsWorld->removeConstraint(m_pickConstraint);
delete m_pickConstraint;
//printf("removed constraint %i",gPickingConstraintId);
m_pickConstraint = 0;
pickedBody->forceActivationState(ACTIVE_TAG);
pickedBody->setDeactivationTime( 0.f );
if (pickedBody->getUserPointer())
{
///deal with controls in a special way
GL_DialogControl* ctrl = (GL_DialogControl*)pickedBody->getUserPointer();
if (ctrl->getType()==GL_SLIDER_CONTROL)
{
GL_SliderControl* sliderControl = (GL_SliderControl*) ctrl;
btSliderConstraint* slider = 0;
btTypedConstraint* constraint = sliderControl->getConstraint();
if (constraint->getConstraintType() == SLIDER_CONSTRAINT_TYPE)
{
slider = (btSliderConstraint*)constraint;
}
if (slider)
{
btScalar linDepth = slider->getLinearPos();
btScalar lowLim = slider->getLowerLinLimit();
btScalar hiLim = slider->getUpperLinLimit();
slider->setPoweredLinMotor(false);
if(linDepth <= lowLim)
{
slider->setLowerLinLimit(lowLim);
slider->setUpperLinLimit(lowLim);
}
else if(linDepth > hiLim)
{
slider->setLowerLinLimit(hiLim);
slider->setUpperLinLimit(hiLim);
}
else
{
slider->setLowerLinLimit(linDepth);
slider->setUpperLinLimit(linDepth);
}
}
}
}
pickedBody = 0;
}
}
break;
}
default:
{
}
}
return false;
}
btVector3 GL_DialogDynamicsWorld::getRayTo(int x,int y)
{
float cameraDistance = m_screenHeight/2;//m_screenWidth/2;//1.f;
btVector3 cameraTargetPosition(0,0,0);
btVector3 cameraUp(0,-1,0);
if (1)//_ortho)
{
btScalar aspect;
btVector3 extents;
if (m_screenWidth> m_screenHeight)
{
aspect = m_screenWidth / (btScalar)m_screenHeight;
extents.setValue(aspect * 1.0f, 1.0f,0);
} else
{
cameraDistance = m_screenWidth/2;
aspect = m_screenHeight / (btScalar)m_screenWidth;
extents.setValue(1.0f, aspect*1.f,0);
}
extents *= cameraDistance;
btVector3 lower = cameraTargetPosition - extents;
btVector3 upper = cameraTargetPosition + extents;
btScalar u = x / btScalar(m_screenWidth);
btScalar v = (m_screenHeight - y) / btScalar(m_screenHeight);
btVector3 p(0,0,0);
p.setValue(
(1.0f - u) * lower.getX() + u * upper.getX(),
-((1.0f - v) * lower.getY() + v * upper.getY()),
cameraTargetPosition.getZ());
return p;
}
float top = 1.f;
float bottom = -1.f;
float nearPlane = 1.f;
float tanFov = (top-bottom)*0.5f / nearPlane;
float fov = 2.0 * atanf (tanFov);
btVector3 cameraPosition(0,0,-100);
btVector3 rayFrom = cameraPosition;
btVector3 rayForward = (cameraTargetPosition-cameraPosition);
rayForward.normalize();
float farPlane = 10000.f;
rayForward*= farPlane;
btVector3 rightOffset;
btVector3 vertical = cameraUp;
btVector3 hor;
hor = rayForward.cross(vertical);
hor.normalize();
vertical = hor.cross(rayForward);
vertical.normalize();
float tanfov = tanf(0.5f*fov);
hor *= 2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
btScalar aspect;
if (m_screenWidth > m_screenHeight)
{
aspect = m_screenWidth / (btScalar)m_screenHeight;
hor*=aspect;
} else
{
aspect = m_screenHeight / (btScalar)m_screenWidth;
vertical*=aspect;
}
btVector3 rayToCenter = rayFrom + rayForward;
btVector3 dHor = hor * 1.f/float(m_screenWidth);
btVector3 dVert = vertical * 1.f/float(m_screenHeight);
btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
rayTo += x * dHor;
rayTo -= y * dVert;
//rayTo += y * dVert;
return rayTo;
}
void GL_DialogDynamicsWorld::mouseMotionFunc(int x,int y)
{
if (m_pickConstraint)
{
//move the constraint pivot
btPoint2PointConstraint* p2p = static_cast<btPoint2PointConstraint*>(m_pickConstraint);
if (p2p)
{
//keep it at the same picking distance
btVector3 newRayTo = getRayTo(x,y);
btVector3 rayFrom;
btVector3 oldPivotInB = p2p->getPivotInB();
btVector3 newPivotB;
if (1)//_ortho)
{
newPivotB = oldPivotInB;
newPivotB.setX(newRayTo.getX());
newPivotB.setY(newRayTo.getY());
} else
{
//rayFrom = m_cameraPosition;
// btVector3 dir = newRayTo-rayFrom;
// dir.normalize();
// dir *= gOldPickingDist;
// newPivotB = rayFrom + dir;
}
p2p->setPivotB(newPivotB);
}
}
float dx, dy;
dx = x - m_mouseOldX;
dy = y - m_mouseOldY;
m_mouseOldX = x;
m_mouseOldY = y;
// updateCamera();
}

View File

@@ -0,0 +1,91 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
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.
*/
#ifndef GL_DIALOG_DYNAMICS_WORLD_H
#define GL_DIALOG_DYNAMICS_WORLD_H
class btDiscreteDynamicsWorld;
class GL_DialogWindow;
class btDefaultCollisionConfiguration;
struct btDbvtBroadphase;
class btSequentialImpulseConstraintSolver;
class btCollisionDispatcher;
class btVoronoiSimplexSolver;
class btMinkowskiPenetrationDepthSolver;
class btCollisionObject;
class btTypedConstraint;
struct GL_ToggleControl;
struct GL_SliderControl;
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btVector3.h"
class GL_DialogDynamicsWorld
{
btDefaultCollisionConfiguration* m_collisionConfiguration;
btDbvtBroadphase* m_broadphase;
btSequentialImpulseConstraintSolver* m_constraintSolver;
btCollisionDispatcher* m_dispatcher;
btVoronoiSimplexSolver* m_simplexSolver;
btMinkowskiPenetrationDepthSolver* m_pdSolver;
btDiscreteDynamicsWorld* m_dynamicsWorld;
btCollisionObject* m_lowerBorder;
btCollisionObject* m_upperBorder;
btCollisionObject* m_leftBorder;
btCollisionObject* m_rightBorder;
btAlignedObjectArray<GL_DialogWindow*> m_dialogs;
int m_screenWidth;
int m_screenHeight;
///for picking
int m_mouseOldX;
int m_mouseOldY;
int m_mouseButtons;
///constraint for mouse picking
btTypedConstraint* m_pickConstraint;
btVector3 getRayTo(int x,int y);
public:
GL_DialogDynamicsWorld();
virtual ~GL_DialogDynamicsWorld();
virtual void setScreenSize(int width, int height);
virtual GL_DialogWindow* createDialog(int horPos,int vertPos,int dialogWidth,int dialogHeight, const char* dialogTitle );
GL_ToggleControl* createToggle(GL_DialogWindow* dialog, const char* toggleText);
GL_SliderControl* createSlider(GL_DialogWindow* dialog, const char* sliderText);
virtual void draw(btScalar timeStep);
virtual bool mouseFunc(int button, int state, int x, int y);
virtual void mouseMotionFunc(int x,int y);
};
#endif //GL_DIALOG_DYNAMICS_WORLD_H

View File

@@ -0,0 +1,519 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
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 "GL_DialogWindow.h"
#include "GlutStuff.h"
#include "GLDebugFont.h"
#include "btBulletDynamicsCommon.h"
// ---------------------------------------------------------------------------
// Extensions
typedef void (APIENTRY * PFNGLBindBufferARB)(GLenum target, GLuint buffer);
typedef void (APIENTRY * PFNGLBindProgramARB)(GLenum target, GLuint program);
typedef GLuint (APIENTRY * PFNGLGetHandleARB)(GLenum pname);
typedef void (APIENTRY * PFNGLUseProgramObjectARB)(GLuint programObj);
typedef void (APIENTRY * PFNGLTexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
typedef void (APIENTRY * PFNGLActiveTextureARB)(GLenum texture);
typedef void (APIENTRY * PFNGLClientActiveTextureARB)(GLenum texture);
typedef void (APIENTRY * PFNGLBlendEquation)(GLenum mode);
typedef void (APIENTRY * PFNGLBlendEquationSeparate)(GLenum srcMode, GLenum dstMode);
typedef void (APIENTRY * PFNGLBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
PFNGLBindBufferARB glBindBufferARB = NULL;
PFNGLBindProgramARB glBindProgramARB = NULL;
PFNGLGetHandleARB glGetHandleARB = NULL;
PFNGLUseProgramObjectARB glUseProgramObjectARB = NULL;
PFNGLTexImage3D glTexImage3D = NULL;
PFNGLActiveTextureARB glActiveTextureARB = NULL;
PFNGLClientActiveTextureARB glClientActiveTextureARB = NULL;
PFNGLBlendEquation glBlendEquation = NULL;
PFNGLBlendEquationSeparate glBlendEquationSeparate = NULL;
PFNGLBlendFuncSeparate glBlendFuncSeparate = NULL;
#ifndef GL_ARRAY_BUFFER_ARB
# define GL_ARRAY_BUFFER_ARB 0x8892
#endif
#ifndef GL_ELEMENT_ARRAY_BUFFER_ARB
# define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
#endif
#ifndef GL_ARRAY_BUFFER_BINDING_ARB
# define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
#endif
#ifndef GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB
# define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
#endif
#ifndef GL_VERTEX_PROGRAM_ARB
# define GL_VERTEX_PROGRAM_ARB 0x8620
#endif
#ifndef GL_FRAGMENT_PROGRAM_ARB
# define GL_FRAGMENT_PROGRAM_ARB 0x8804
#endif
#ifndef GL_PROGRAM_OBJECT_ARB
# define GL_PROGRAM_OBJECT_ARB 0x8B40
#endif
#ifndef GL_TEXTURE_3D
# define GL_TEXTURE_3D 0x806F
#endif
#ifndef GL_TEXTURE0_ARB
# define GL_TEXTURE0_ARB 0x84C0
#endif
#ifndef GL_ACTIVE_TEXTURE_ARB
# define GL_ACTIVE_TEXTURE_ARB 0x84E0
#endif
#ifndef GL_MAX_TEXTURE_UNITS_ARB
# define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
#endif
#ifndef GL_TEXTURE_RECTANGLE_ARB
# define GL_TEXTURE_RECTANGLE_ARB 0x84F5
#endif
#ifndef GL_FUNC_ADD
# define GL_FUNC_ADD 0x8006
#endif
#ifndef GL_BLEND_EQUATION
# define GL_BLEND_EQUATION 0x8009
#endif
#ifndef GL_BLEND_EQUATION_RGB
# define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
#endif
#ifndef GL_BLEND_EQUATION_ALPHA
# define GL_BLEND_EQUATION_ALPHA 0x883D
#endif
#ifndef GL_BLEND_SRC_RGB
# define GL_BLEND_SRC_RGB 0x80C9
#endif
#ifndef GL_BLEND_DST_RGB
# define GL_BLEND_DST_RGB 0x80C8
#endif
#ifndef GL_BLEND_SRC_ALPHA
# define GL_BLEND_SRC_ALPHA 0x80CB
#endif
#ifndef GL_BLEND_DST_ALPHA
# define GL_BLEND_DST_ALPHA 0x80CA
#endif
GL_DialogWindow::GL_DialogWindow(int horPos,int vertPos,int dialogWidth,int dialogHeight, btCollisionObject* collisionObject,const char* dialogTitle)
:m_dialogHorPos(horPos),
m_dialogVertPos(vertPos),
m_dialogWidth(dialogWidth),
m_dialogHeight(dialogHeight),
m_screenWidth(0),
m_screenHeight(0),
m_MaxClipPlanes(-1),
m_collisionObject(collisionObject),
m_dialogTitle(dialogTitle)
{
}
void GL_DialogWindow::setScreenSize(int width, int height)
{
m_screenWidth = width;
m_screenHeight = height;
}
GL_DialogWindow::~GL_DialogWindow()
{
}
static void drawLine(int _X0, int _Y0, int _X1, int _Y1, unsigned int _Color0, unsigned int _Color1)
{
const GLfloat dx = +0.5f;
const GLfloat dy = -0.5f;
bool antiAliased = false;
if( antiAliased )
glEnable(GL_LINE_SMOOTH);
else
glDisable(GL_LINE_SMOOTH);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_LINES);
glColor4ub(GLubyte(_Color0>>16), GLubyte(_Color0>>8), GLubyte(_Color0), GLubyte(_Color0>>24));
glVertex2f((GLfloat)_X0+dx, (GLfloat)_Y0+dy);
glColor4ub(GLubyte(_Color1>>16), GLubyte(_Color1>>8), GLubyte(_Color1), GLubyte(_Color1>>24));
glVertex2f((GLfloat)_X1+dx, (GLfloat)_Y1+dy);
glEnd();
glDisable(GL_LINE_SMOOTH);
}
static void drawRect(int horStart, int vertStart, int horEnd, int vertEnd, unsigned int argbColor00,unsigned int argbColor10,unsigned int argbColor01,unsigned int argbColor11)
{
float dx = 0;
float dy = 0;
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glColor4ub(GLubyte(argbColor00>>16), GLubyte(argbColor00>>8), GLubyte(argbColor00), GLubyte(argbColor00>>24));
glVertex2f((GLfloat)horStart+dx, (GLfloat)vertStart+dy);
glColor4ub(GLubyte(argbColor10>>16), GLubyte(argbColor10>>8), GLubyte(argbColor10), GLubyte(argbColor10>>24));
glVertex2f((GLfloat)horEnd+dx, (GLfloat)vertStart+dy);
glColor4ub(GLubyte(argbColor11>>16), GLubyte(argbColor11>>8), GLubyte(argbColor11), GLubyte(argbColor11>>24));
glVertex2f((GLfloat)horEnd+dx, (GLfloat)vertEnd+dy);
glColor4ub(GLubyte(argbColor01>>16), GLubyte(argbColor01>>8), GLubyte(argbColor01), GLubyte(argbColor01>>24));
glVertex2f((GLfloat)horStart+dx, (GLfloat)vertEnd+dy);
glEnd();
}
void GL_DialogWindow::draw(btScalar deltaTime)
{
if (!m_screenWidth || !m_screenHeight)
return;
m_dialogHorPos = m_collisionObject->getWorldTransform().getOrigin()[0]+m_screenWidth/2-m_dialogWidth/2;
m_dialogVertPos = m_collisionObject->getWorldTransform().getOrigin()[1]+m_screenHeight/2-m_dialogHeight/2;
saveOpenGLState();
//drawRect(m_dialogHorPos,m_dialogVertPos,m_dialogHorPos+m_dialogWidth,m_dialogVertPos+m_dialogHeight,0xa6000000);
unsigned int argbColor = 0x86000000;
int charHeight = 16;
int charWidth = 10;
int titleHeight = charHeight + 2;
drawRect(m_dialogHorPos,m_dialogVertPos,m_dialogHorPos+m_dialogWidth-1,m_dialogVertPos+titleHeight,argbColor,argbColor,argbColor,argbColor);
//const unsigned int COL0 = 0x50ffffff;
const unsigned int COL0 = 0xffffffff;
const unsigned int COL1 = 0xff1f1f1f;
drawRect(m_dialogHorPos,m_dialogVertPos,m_dialogHorPos+m_dialogWidth-1,m_dialogVertPos+1,COL0,COL0,COL1,COL1);
argbColor = 0x864f4f4f;
drawRect(m_dialogHorPos+1,m_dialogVertPos+titleHeight,m_dialogHorPos+m_dialogWidth-1,m_dialogVertPos+m_dialogHeight,argbColor,argbColor,argbColor,argbColor);
int y = m_dialogVertPos+charHeight+1;
glLineWidth(3);
drawLine(m_dialogHorPos, y, m_dialogHorPos+m_dialogWidth-1, y, 0x80afafaf,0x80afafaf);
unsigned int clight = 0x5FFFFFFF; // bar contour
drawLine(m_dialogHorPos, m_dialogVertPos, m_dialogHorPos, m_dialogVertPos+m_dialogHeight, clight,clight);
drawLine(m_dialogHorPos, m_dialogVertPos, m_dialogHorPos+m_dialogWidth, m_dialogVertPos, clight,clight);
drawLine(m_dialogHorPos+m_dialogWidth, m_dialogVertPos, m_dialogHorPos+m_dialogWidth, m_dialogVertPos+m_dialogHeight, clight,clight);
drawLine(m_dialogHorPos, m_dialogVertPos+m_dialogHeight, m_dialogHorPos+m_dialogWidth, m_dialogVertPos+m_dialogHeight, clight,clight);
int dshad = 3; // bar shadows
unsigned int cshad = (((0x40000000>>24)/2)<<24) & 0xFF000000;
drawRect(m_dialogHorPos, m_dialogVertPos+m_dialogHeight, m_dialogHorPos+dshad, m_dialogVertPos+m_dialogHeight+dshad, 0, cshad, 0, 0);
drawRect(m_dialogHorPos+dshad+1, m_dialogVertPos+m_dialogHeight, m_dialogHorPos+m_dialogWidth-1, m_dialogVertPos+m_dialogHeight+dshad, cshad, cshad, 0, 0);
drawRect(m_dialogHorPos+m_dialogWidth, m_dialogVertPos+m_dialogHeight, m_dialogHorPos+m_dialogWidth+dshad, m_dialogVertPos+m_dialogHeight+dshad, cshad, 0, 0, 0);
drawRect(m_dialogHorPos+m_dialogWidth, m_dialogVertPos, m_dialogHorPos+m_dialogWidth+dshad, m_dialogVertPos+dshad, 0, 0, cshad, 0);
drawRect(m_dialogHorPos+m_dialogWidth, m_dialogVertPos+dshad+1, m_dialogHorPos+m_dialogWidth+dshad, m_dialogVertPos+m_dialogHeight-1, cshad, 0, cshad, 0);
int yInc = 16;
int curHorPos = m_dialogHorPos+5;
int curVertPos = m_dialogVertPos;
curVertPos += yInc;
GLDebugDrawString(m_dialogHorPos+m_dialogWidth/2-((strlen(m_dialogTitle)/2)*charWidth),m_dialogVertPos+yInc ,m_dialogTitle);
curVertPos += 20;
for (int i=0;i<m_controls.size();i++)
{
m_controls[i]->draw(curHorPos,curVertPos,deltaTime);
}
restoreOpenGLState();
}
void GL_DialogWindow::saveOpenGLState()
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
if( glActiveTextureARB )
{
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &m_PrevActiveTextureARB);
int maxTexUnits = 1;
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTexUnits);
maxTexUnits = max(1, min(32, maxTexUnits));
for( int i=0; i<maxTexUnits; ++i )
{
glActiveTextureARB(GL_TEXTURE0_ARB+i);
m_PrevActiveTexture1D[i] = glIsEnabled(GL_TEXTURE_1D);
m_PrevActiveTexture2D[i] = glIsEnabled(GL_TEXTURE_2D);
m_PrevActiveTexture3D[i] = glIsEnabled(GL_TEXTURE_3D);
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
}
glActiveTextureARB(GL_TEXTURE0_ARB);
}
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
GLint Vp[4];
glGetIntegerv(GL_VIEWPORT, Vp);
if( m_screenWidth>0 && m_screenHeight>0 )
{
Vp[0] = 0;
Vp[1] = 0;
Vp[2] = m_screenWidth-1;
Vp[3] = m_screenHeight-1;
glViewport(Vp[0], Vp[1], Vp[2], Vp[3]);
}
glLoadIdentity();
glOrtho(Vp[0], Vp[0]+Vp[2], Vp[1]+Vp[3], Vp[1], -1, 1);
glGetIntegerv(GL_VIEWPORT, m_ViewportInit);
glGetFloatv(GL_PROJECTION_MATRIX, m_ProjMatrixInit);
glGetFloatv(GL_LINE_WIDTH, &m_PrevLineWidth);
glDisable(GL_POLYGON_STIPPLE);
glLineWidth(1);
glDisable(GL_LINE_SMOOTH);
glDisable(GL_LINE_STIPPLE);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &m_PrevTexEnv);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glGetIntegerv(GL_POLYGON_MODE, m_PrevPolygonMode);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_ALPHA_TEST);
//glEnable(GL_ALPHA_TEST);
//glAlphaFunc(GL_GREATER, 0);
glDisable(GL_FOG);
glDisable(GL_LOGIC_OP);
glDisable(GL_SCISSOR_TEST);
if( m_MaxClipPlanes<0 )
{
glGetIntegerv(GL_MAX_CLIP_PLANES, &m_MaxClipPlanes);
if( m_MaxClipPlanes<0 || m_MaxClipPlanes>255 )
m_MaxClipPlanes = 6;
}
for( int i=0; i<m_MaxClipPlanes; ++i )
glDisable(GL_CLIP_PLANE0+i);
m_PrevTexture = 0;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &m_PrevTexture);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_INDEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_EDGE_FLAG_ARRAY);
if( glBindBufferARB!=NULL )
{
m_PrevArrayBufferARB = m_PrevElementArrayBufferARB = 0;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &m_PrevArrayBufferARB);
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &m_PrevElementArrayBufferARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
if( glBindProgramARB!=NULL )
{
m_PrevVertexProgramARB = glIsEnabled(GL_VERTEX_PROGRAM_ARB);
m_PrevFragmentProgramARB = glIsEnabled(GL_FRAGMENT_PROGRAM_ARB);
glDisable(GL_VERTEX_PROGRAM_ARB);
glDisable(GL_FRAGMENT_PROGRAM_ARB);
}
if( glGetHandleARB!=NULL && glUseProgramObjectARB!=NULL )
{
m_PrevProgramObjectARB = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
glUseProgramObjectARB(0);
}
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
if( glTexImage3D!=NULL )
{
m_PrevTexture3D = glIsEnabled(GL_TEXTURE_3D);
glDisable(GL_TEXTURE_3D);
}
if( m_SupportTexRect )
{
m_PrevTexRectARB = glIsEnabled(GL_TEXTURE_RECTANGLE_ARB);
glDisable(GL_TEXTURE_RECTANGLE_ARB);
}
if( glBlendEquationSeparate!=NULL )
{
glGetIntegerv(GL_BLEND_EQUATION_RGB, &m_PrevBlendEquationRGB);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &m_PrevBlendEquationAlpha);
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
}
if( glBlendFuncSeparate!=NULL )
{
glGetIntegerv(GL_BLEND_SRC_RGB, &m_PrevBlendSrcRGB);
glGetIntegerv(GL_BLEND_DST_RGB, &m_PrevBlendDstRGB);
glGetIntegerv(GL_BLEND_SRC_ALPHA, &m_PrevBlendSrcAlpha);
glGetIntegerv(GL_BLEND_DST_ALPHA, &m_PrevBlendDstAlpha);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
if( glBlendEquation!=NULL )
{
glGetIntegerv(GL_BLEND_EQUATION, &m_PrevBlendEquation);
glBlendEquation(GL_FUNC_ADD);
}
}
void GL_DialogWindow::restoreOpenGLState()
{
glBindTexture(GL_TEXTURE_2D, m_PrevTexture);
if( glBindBufferARB!=NULL )
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_PrevArrayBufferARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_PrevElementArrayBufferARB);
}
if( glBindProgramARB!=NULL )
{
if( m_PrevVertexProgramARB )
glEnable(GL_VERTEX_PROGRAM_ARB);
if( m_PrevFragmentProgramARB )
glEnable(GL_FRAGMENT_PROGRAM_ARB);
}
if( glGetHandleARB!=NULL && glUseProgramObjectARB!=NULL )
glUseProgramObjectARB(m_PrevProgramObjectARB);
if( glTexImage3D!=NULL && m_PrevTexture3D )
glEnable(GL_TEXTURE_3D);
if( m_SupportTexRect && m_PrevTexRectARB )
glEnable(GL_TEXTURE_RECTANGLE_ARB);
if( glBlendEquation!=NULL )
glBlendEquation(m_PrevBlendEquation);
if( glBlendEquationSeparate!=NULL )
glBlendEquationSeparate(m_PrevBlendEquationRGB, m_PrevBlendEquationAlpha);
if( glBlendFuncSeparate!=NULL )
glBlendFuncSeparate(m_PrevBlendSrcRGB, m_PrevBlendDstRGB, m_PrevBlendSrcAlpha, m_PrevBlendDstAlpha);
glPolygonMode(GL_FRONT, m_PrevPolygonMode[0]);
glPolygonMode(GL_BACK, m_PrevPolygonMode[1]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_PrevTexEnv);
glLineWidth(m_PrevLineWidth);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glPopClientAttrib();
glPopAttrib();
if( glActiveTextureARB )
{
int maxTexUnits = 1;
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTexUnits);
maxTexUnits = max(1, min(32, maxTexUnits));
for( int i=0; i<maxTexUnits; ++i )
{
glActiveTextureARB(GL_TEXTURE0_ARB+i);
if( m_PrevActiveTexture1D[i] )
glEnable(GL_TEXTURE_1D);
if( m_PrevActiveTexture2D[i] )
glEnable(GL_TEXTURE_2D);
if( m_PrevActiveTexture3D[i] )
glEnable(GL_TEXTURE_3D);
}
glActiveTextureARB(m_PrevActiveTextureARB);
}
}
void GL_TextControl::draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime)
{
for (int i=0;i<m_textLines.size();i++)
{
GLDebugDrawString(parentHorPos,parentVertPos,m_textLines[i]);
parentVertPos+=20;
}
}
void GL_ToggleControl::draw(int& parentHorPos2,int& parentVertPos2,btScalar deltaTime)
{
int controlHorPos = m_toggleBody->getWorldTransform().getOrigin()[0]+m_parentWindow->getScreenWidth()/2;//-m_parentWindow->getDialogWidth()/2;
int controlVertPos = m_toggleBody->getWorldTransform().getOrigin()[1]+m_parentWindow->getScreenHeight()/2;//-m_parentWindow->getDialogHeight()/2;
int parentHorPos = controlHorPos-8;
int parentVertPos = controlVertPos-8;
unsigned int grey = 0xff6f6f6f;
drawRect(parentHorPos, parentVertPos, parentHorPos+16, parentVertPos+16, grey, grey, grey, grey);
int borderSize = 2;
unsigned int white = 0xffefefef;
drawRect(parentHorPos+borderSize, parentVertPos+borderSize, parentHorPos+16-borderSize, parentVertPos+16-borderSize, white,white,white,white);
if (m_active)
{
//unsigned int red = 0xff8f0000;
unsigned int white = 0xff8f0000;
unsigned int black = 0xff1f1f1f;
borderSize = 4;
drawRect(parentHorPos+borderSize, parentVertPos+borderSize, parentHorPos+16-borderSize, parentVertPos+16-borderSize, black,black,black,black);
}
btVector3 rgb(1,1,0);
if (!m_active)
{
rgb.setValue(1,1,1);
}
GLDebugDrawStringInternal(parentHorPos2,parentVertPos+16,m_toggleText,rgb);
parentVertPos2+=20;
}
void GL_SliderControl::draw(int& parentHorPos2,int& parentVertPos2,btScalar deltaTime)
{
int controlHorPos = m_sliderBody->getWorldTransform().getOrigin()[0]+m_parentWindow->getScreenWidth()/2;
int controlVertPos = m_sliderBody->getWorldTransform().getOrigin()[1]+m_parentWindow->getScreenHeight()/2;
int parentHorPos = controlHorPos-8;
int parentVertPos = controlVertPos-8;
unsigned int grey = 0xff6f6f6f;
int borderSize = 2;
unsigned int white = 0xffefefef;
drawRect(parentHorPos2+80+borderSize, parentVertPos2+borderSize, parentHorPos2+m_parentWindow->getDialogWidth()-16-borderSize, parentVertPos2+2-borderSize, white,white,white,white);
drawRect(parentHorPos, parentVertPos, parentHorPos+16, parentVertPos+16, grey, grey, grey, grey);
drawRect(parentHorPos+borderSize, parentVertPos+borderSize, parentHorPos+16-borderSize, parentVertPos+16-borderSize, white,white,white,white);
btVector3 rgb(1,1,1);
GLDebugDrawStringInternal(parentHorPos2,parentVertPos2+8,m_sliderText,rgb);
parentVertPos2+=20;
}

View File

@@ -0,0 +1,256 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
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.
*/
#ifndef GL_DIALOG_WINDOW_H
#define GL_DIALOG_WINDOW_H
class btCollisionObject;
#include "GlutStuff.h"
#include "LinearMath/btScalar.h"
#include "LinearMath/btAlignedObjectArray.h"
class btTypedConstraint;
class GL_DialogWindow;
enum GL_DIALOG_CONTROL_TYPES
{
GL_TEXT_CONTROL=1,
GL_TOGGLE_CONTROL,
GL_SLIDER_CONTROL,
GL_CONTROL_MAX_TYPE
};
class GL_DialogControl
{
protected:
int m_type;
public:
virtual ~GL_DialogControl()
{
}
virtual void draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime)=0;
int getType() const
{
return m_type;
}
};
struct GL_TextControl : public GL_DialogControl
{
public:
btAlignedObjectArray<const char*> m_textLines;
GL_TextControl()
{
m_type = GL_TEXT_CONTROL;
}
virtual void draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime);
};
struct GL_ToggleControl : public GL_DialogControl
{
btCollisionObject* m_toggleBody;
GL_DialogWindow* m_parentWindow;
const char* m_toggleText;
public:
bool m_active;
GL_ToggleControl(const char* toggleText,btCollisionObject* toggleBody, GL_DialogWindow* parentWindow)
:m_toggleBody(toggleBody),
m_parentWindow(parentWindow),
m_toggleText(toggleText),
m_active(false)
{
m_type = GL_TOGGLE_CONTROL;
}
virtual void draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime);
};
struct GL_SliderControl : public GL_DialogControl
{
btCollisionObject* m_sliderBody;
GL_DialogWindow* m_parentWindow;
btScalar m_lowerLimit;
btScalar m_upperLimit;
btTypedConstraint* m_constraint;
const char* m_sliderText;
public:
GL_SliderControl(const char* sliderText,btCollisionObject* sliderBody, GL_DialogWindow* parentWindow, btScalar lowerLimit,btScalar upperLimit,btTypedConstraint* constaint)
:m_sliderBody(sliderBody),
m_parentWindow(parentWindow),
m_sliderText(sliderText),
m_lowerLimit(lowerLimit),
m_upperLimit(upperLimit),
m_constraint(constaint)
{
m_type = GL_SLIDER_CONTROL;
}
virtual void draw(int& parentHorPos,int& parentVertPos,btScalar deltaTime);
btScalar btGetFraction();
btScalar getLowerLimit()
{
return m_lowerLimit;
}
btScalar getUpperLimit()
{
return m_upperLimit;
}
btTypedConstraint* getConstraint()
{
return m_constraint;
}
};
///Very basic OpenGL Graphical Userinterface Window with text, toggle, slider control
class GL_DialogWindow
{
int m_dialogHorPos;
int m_dialogVertPos;
int m_dialogWidth;
int m_dialogHeight;
int m_screenWidth;
int m_screenHeight;
const char* m_dialogTitle;
//saved OpenGL settings
GLfloat m_PrevLineWidth;
GLint m_PrevTexEnv;
GLint m_PrevPolygonMode[2];
GLint m_MaxClipPlanes;
GLint m_PrevTexture;
GLint m_PrevArrayBufferARB;
GLint m_PrevElementArrayBufferARB;
GLboolean m_PrevVertexProgramARB;
GLboolean m_PrevFragmentProgramARB;
GLuint m_PrevProgramObjectARB;
GLboolean m_PrevTexture3D;
GLboolean m_PrevActiveTexture1D[32];
GLboolean m_PrevActiveTexture2D[32];
GLboolean m_PrevActiveTexture3D[32];
GLint m_PrevActiveTextureARB;
bool m_SupportTexRect;
GLboolean m_PrevTexRectARB;
GLint m_PrevBlendEquation;
GLint m_PrevBlendEquationRGB;
GLint m_PrevBlendEquationAlpha;
GLint m_PrevBlendSrcRGB;
GLint m_PrevBlendDstRGB;
GLint m_PrevBlendSrcAlpha;
GLint m_PrevBlendDstAlpha;
GLint m_ViewportInit[4];
GLfloat m_ProjMatrixInit[16];
btCollisionObject* m_collisionObject;
btAlignedObjectArray<GL_DialogControl*> m_controls;
protected:
void saveOpenGLState();
void restoreOpenGLState();
// void drawLine(int _X0, int _Y0, int _X1, int _Y1, unsigned int _Color0, unsigned int _Color1, bool antiAliased);
// void drawRect(int horStart, int vertStart, int horEnd, int vertEnd, unsigned int argbColor00,unsigned int argbColor10,unsigned int argbColor01,unsigned int argbColor11);
public:
GL_DialogWindow(int horPos,int vertPos,int dialogWidth,int dialogHeight,btCollisionObject* colObject, const char* dialogTitle);
virtual ~GL_DialogWindow();
void draw(btScalar deltaTime);
void setScreenSize(int width, int height);
void setStartPosition(int dialogHorPos,int dialogVertPos);
void addControl(GL_DialogControl* control)
{
m_controls.push_back(control);
}
void removeControl(GL_DialogControl* control)
{
m_controls.remove(control);
}
btCollisionObject* getCollisionObject()
{
return m_collisionObject;
}
int getDialogHorPos() const
{
return m_dialogHorPos;
}
int getDialogVertPos() const
{
return m_dialogVertPos;
}
int getDialogWidth() const
{
return m_dialogWidth;
}
int getDialogHeight() const
{
return m_dialogHeight;
}
int getScreenWidth() const
{
return m_screenWidth;
}
int getScreenHeight() const
{
return m_screenHeight;
}
int getNumControls() const
{
return m_controls.size();
}
const GL_DialogControl* getControl(int index) const
{
return m_controls[index];
}
GL_DialogControl* getControl(int index)
{
return m_controls[index];
}
};
#endif //GL_DIALOG_WINDOW_H

View File

@@ -95,6 +95,7 @@ int glutmain(int argc, char **argv,int width,int height,const char* title,DemoAp
//createMenu();
glutIdleFunc(glutMoveAndDisplayCallback);
glutMouseFunc(glutMouseFuncCallback);
glutPassiveMotionFunc(glutMotionFuncCallback);
glutMotionFunc(glutMotionFuncCallback);
glutDisplayFunc( glutDisplayCallback );