Code: Select all
#include "config.h"
#include "time.h"
//Global bullet vars
static bool Done = false;
static btDiscreteDynamicsWorld *dynamicsWorld;
static list<btRigidBody *> objects;
//Global Irrlicht vars
static IrrlichtDevice *device;
static IVideoDriver *driver;
static ISceneManager *smgr;
static ITimer *timer;
//static IGUIEnvironment *guienv;
//static IFileSystem *filesys;
//static ILogger *logger;
//Bullet Related Functions
static void createStartScene();
static void createBox(const btVector3 &TPosition, const vector3df &TScale, btScalar TMass);
static void createSphere(const btVector3 &TPosition, btScalar TRadius, btScalar TMass);
void UpdatePhysics(u32 TDeltaTime);
static void UpdateRender(btRigidBody *TObject);
static void ClearObjects();
static int GetRandInt(int TMax) {return rand() % TMax; }
class EventReceiverClass : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent &TEvent)
{
if(TEvent.EventType == EET_KEY_INPUT_EVENT && !TEvent.KeyInput.PressedDown)
{
switch(TEvent.KeyInput.Key)
{
case KEY_ESCAPE:
Done=true;
break;
case KEY_KEY_Q:
createBox(btVector3(GetRandInt(10) - 5.0f, 7.0f, GetRandInt(10) - 5.0f), vector3df(GetRandInt(3)+0.5f,GetRandInt(3)+0.5f, GetRandInt(3)+0.5f),1.0f);
break;
case KEY_KEY_W:
createSphere(btVector3(GetRandInt(10) - 5.0f, 7.0f, GetRandInt(10) - 5.0f), GetRandInt(5) / 5.0f + 0.2f, 1.0f);
break;
case KEY_KEY_E:
createStartScene();
break;
default:
return false;
break;
}
return true;
}
return false;
}
};
int main()
{
srand(time(NULL));
int screenHeight = 800, screenWidth = 600;
EventReceiverClass receiver;
device = createDevice(EDT_OPENGL, dimension2d<u32>(screenHeight, screenWidth), 32, false, false, false, &receiver);
if (device == 0)
{
return 1;
}
//guienv = device->getGUIEnvironment();
timer = device->getTimer();
driver = device->getVideoDriver();
smgr = device->getSceneManager();
device->getCursorControl()->setVisible(false);
btBroadphaseInterface *broadPhase = new btAxisSweep3(btVector3(-1000,-1000,-1000), btVector3(1000,1000,1000));
btDefaultCollisionConfiguration *collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher *dispatcher = new btCollisionDispatcher(collisionConfiguration);
btSequentialImpulseConstraintSolver *solver = new btSequentialImpulseConstraintSolver();
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadPhase, solver, collisionConfiguration);
ICameraSceneNode *camera = smgr->addCameraSceneNodeFPS(0,100,25);
camera->setPosition(vector3df(0,5,-5));
camera->setTarget(vector3df(0,0,0));
/*IGUISkin* skin = guienv->getSkin();
skin->setColor(EGDC_BUTTON_TEXT, SColor(255,200,200,200));
guienv->addStaticText(L"Hit Q to spawn a cube, W for a sphere and E to reset or escape to exit.", rect<s32>(0,0,200,100), false);
IGUIStaticText* versionText = guienv->addStaticText(L"", rect<s32>(0,0,300,200),false);
versionText->setText(string);*/
smgr->addLightSceneNode(0, vector3df(2, 5, -2), SColorf(4, 4, 4, 1));
createStartScene();
driver->getTexture("resources/textures/tex.jpg");
driver->getTexture("resources/textures/tex1.jpg");
u32 timeStamp = timer->getTime(), DeltaTime = 0;
while(Done == false)
{
device->run();
if(device->isWindowActive())
{
DeltaTime = timer->getTime() - timeStamp;
timeStamp = timer->getTime();
UpdatePhysics(DeltaTime);
driver->beginScene(true,true,SColor(255,55,0,155));
smgr->drawAll();
//guienv->drawAll();
driver->endScene();
int FPS = driver->getFPS(), lastFPS = -1;
if(lastFPS != FPS)
{
stringw str = L"COLLISION TEST [";
str += driver->getName();
str += "] FPS:";
str += FPS;
str += " VERSION:";
str += auto__RC_FILEVERSION_STRING;
device->setWindowCaption(str.c_str());
lastFPS=FPS;
}
}
device->yield();
}
ClearObjects();
delete dynamicsWorld;
delete solver;
delete dispatcher;
delete broadPhase;
delete collisionConfiguration;
device->drop();
getchar();
return 0;
}
void UpdatePhysics(u32 TDeltaTime)
{
dynamicsWorld->stepSimulation(TDeltaTime * 0.001f, 60);
for(list<btRigidBody *>::Iterator Iterator = objects.begin(); Iterator != objects.end(); ++Iterator)
{
UpdateRender(*Iterator);
}
}
void createStartScene()
{
ClearObjects();
createBox(btVector3(0.0f,0.0f,0.0f), vector3df(10.0f,0.5f,10.0f), 0.0f);
}
void createBox(const btVector3 &TPosition, const vector3df &TScale, btScalar TMass)
{
ISceneNode *node = smgr->addCubeSceneNode(1.0f);
node->setScale(TScale);
node->setMaterialFlag(EMF_LIGHTING, 1);
node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
node->setMaterialTexture(0,driver->getTexture("resources/textures/tex.jpg"));
btTransform bulletTransform;
bulletTransform.setIdentity();
bulletTransform.setOrigin(TPosition);
btDefaultMotionState *motionState = new btDefaultMotionState(bulletTransform);
btVector3 halfExtents(TScale.X * 0.5f, TScale.Y * 0.5f, TScale.Z * 0.5f);
btCollisionShape *shape = new btBoxShape(halfExtents);
btVector3 localInertia;
shape->calculateLocalInertia(TMass, localInertia);
btRigidBody *rigidBody = new btRigidBody(TMass, motionState, shape, localInertia);
rigidBody->setUserPointer((void*)(node));
dynamicsWorld->addRigidBody(rigidBody);
objects.push_back(rigidBody);
}
void createSphere(const btVector3 &TPosition, btScalar TRadius, btScalar TMass)
{
ISceneNode *node = smgr->addSphereSceneNode(TRadius, 32);
node->setMaterialFlag(EMF_LIGHTING, 1);
node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
node->setMaterialTexture(0,driver->getTexture("resources/textures/tex1.jpg"));
btTransform bulletTransform;
bulletTransform.setIdentity();
bulletTransform.setOrigin(TPosition);
btDefaultMotionState *motionState = new btDefaultMotionState(bulletTransform);
btCollisionShape *shape = new btSphereShape(TRadius);
btVector3 localInertia;
shape->calculateLocalInertia(TMass, localInertia);
btRigidBody *rigidBody = new btRigidBody(TMass,motionState,shape,localInertia);
rigidBody->setUserPointer((void*)(node));
dynamicsWorld->addRigidBody(rigidBody);
objects.push_back(rigidBody);
}
void UpdateRender(btRigidBody *TObject)
{
ISceneNode *node = static_cast<ISceneNode *>(TObject->getUserPointer());
btVector3 point = TObject->getCenterOfMassPosition();
node->setPosition(vector3df((f32)point[0], (f32)point[1], (f32)point[2]));
vector3df Euler;
const btQuaternion& TQuaternion = TObject->getOrientation();
quaternion q(TQuaternion.getX(), TQuaternion.getY(), TQuaternion.getZ(), TQuaternion.getW());
q.toEuler(Euler);
Euler *= RADTODEG;
node->setRotation(Euler);
}
void ClearObjects()
{
for(list<btRigidBody *>::Iterator Iterator = objects.begin(); Iterator != objects.end(); ++Iterator)
{
btRigidBody *object = *Iterator;
ISceneNode *node = static_cast<ISceneNode *>(object->getUserPointer());
node->remove();
dynamicsWorld->removeRigidBody(object);
delete object->getMotionState();
delete object->getCollisionShape();
delete object;
}
objects.clear();
}
Something along those lines should work, this code isn't commented nor can I guarantee that it is particularly useful, it's mostly written from memory and UNTESTED