#include #include extern "C" { #include #include #include } #include #include #include #include "initdevice.hpp" #include "menuhandeler.hpp" #include "lua_api/load_gui.hpp" #include "lua_api/load_game.hpp" #include "lua_api/load_core.hpp" #include "lua_api/load_phys.hpp" #include "callbackhandeler.hpp" using namespace irr; using namespace core; using namespace scene; using namespace video; using namespace io; using namespace gui; btDiscreteDynamicsWorld* World; core::list Objects; void loadLLibs(lua_State* L){ luaopen_base(L); luaopen_table(L); luaopen_io(L); luaopen_string(L); luaopen_math(L); } lua_State* L; IrrlichtDevice* device; void loadIrrLibs(lua_State* L, IrrlichtDevice* device){ printf("Loading guifuncs...\n"); load_guifuncs(L); load_gamefuncs(L); load_corefuncs(L); load_physfuncs(L); } static int GetRandInt(int TMax) { return rand() % TMax; } // Removes all objects from the world void ClearObjects() { for(list::Iterator Iterator = Objects.begin(); Iterator != Objects.end(); ++Iterator) { btRigidBody *Object = *Iterator; // Delete irrlicht node ISceneNode *Node = static_cast(Object->getUserPointer()); Node->remove(); // Remove the object from the world World->removeRigidBody(Object); delete Object; } Objects.clear(); } // Create a box rigid body void CreateBox(ISceneManager* irrScene, const btVector3 &TPosition, const core::vector3df &TScale, btScalar TMass) { // Create an Irrlicht cube scene::ISceneNode *Node = irrScene->addCubeSceneNode(1.0f); Node->setScale(TScale); Node->setMaterialFlag(video::EMF_LIGHTING, 1); Node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); //Node->setMaterialTexture(0, irrDriver->getTexture("rust0.jpg")); // Set the initial position of the object btTransform Transform; Transform.setIdentity(); Transform.setOrigin(TPosition); // Give it a default MotionState btDefaultMotionState *MotionState = new btDefaultMotionState(Transform); // Create the shape btVector3 HalfExtents(TScale.X * 0.5f, TScale.Y * 0.5f, TScale.Z * 0.5f); btCollisionShape *Shape = new btBoxShape(HalfExtents); // Add mass btVector3 LocalInertia; Shape->calculateLocalInertia(TMass, LocalInertia); // Create the rigid body object btRigidBody *RigidBody = new btRigidBody(TMass, MotionState, Shape, LocalInertia); // Store a pointer to the irrlicht node so we can update it later RigidBody->setUserPointer((void *)(Node)); // Add it to the world World->addRigidBody(RigidBody); Objects.push_back(RigidBody); } // Create a sphere rigid body void CreateSphere(ISceneManager* irrScene, const btVector3 &TPosition, btScalar TRadius, btScalar TMass) { // Create an Irrlicht sphere scene::ISceneNode *Node = irrScene->addSphereSceneNode(TRadius, 32); Node->setMaterialFlag(video::EMF_LIGHTING, 1); Node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); //Node->setMaterialTexture(0, irrDriver->getTexture("ice0.jpg")); // Set the initial position of the object btTransform Transform; Transform.setIdentity(); Transform.setOrigin(TPosition); // Give it a default MotionState btDefaultMotionState *MotionState = new btDefaultMotionState(Transform); // Create the shape btCollisionShape *Shape = new btSphereShape(TRadius); // Add mass btVector3 LocalInertia; Shape->calculateLocalInertia(TMass, LocalInertia); // Create the rigid body object btRigidBody *RigidBody = new btRigidBody(TMass, MotionState, Shape, LocalInertia); // Store a pointer to the irrlicht node so we can update it later RigidBody->setUserPointer((void *)(Node)); // Add it to the world World->addRigidBody(RigidBody); Objects.push_back(RigidBody); } // Converts a quaternion to an euler angle void QuaternionToEuler(const btQuaternion &TQuat, btVector3 &TEuler) { btScalar W = TQuat.getW(); btScalar X = TQuat.getX(); btScalar Y = TQuat.getY(); btScalar Z = TQuat.getZ(); float WSquared = W * W; float XSquared = X * X; float YSquared = Y * Y; float ZSquared = Z * Z; TEuler.setX(atan2f(2.0f * (Y * Z + X * W), -XSquared - YSquared + ZSquared + WSquared)); TEuler.setY(asinf(-2.0f * (X * Z - Y * W))); TEuler.setZ(atan2f(2.0f * (X * Y + Z * W), XSquared - YSquared - ZSquared + WSquared)); TEuler *= core::RADTODEG; } // Runs the physics simulation. // - TDeltaTime tells the simulation how much time has passed since the last frame so the simulation can run independently of the frame rate. void UpdatePhysics(u32 TDeltaTime) { World->stepSimulation(TDeltaTime * 0.001f, 60); btRigidBody *TObject; // Relay the object's orientation to irrlicht for(core::list::Iterator it = Objects.begin(); it != Objects.end(); ++it) { //UpdateRender(*Iterator); scene::ISceneNode *Node = static_cast((*it)->getUserPointer()); TObject = *it; // Set position btVector3 Point = TObject->getCenterOfMassPosition(); Node->setPosition(core::vector3df((f32)Point[0], (f32)Point[1], (f32)Point[2])); // Set rotation btVector3 EulerRotation; QuaternionToEuler(TObject->getOrientation(), EulerRotation); Node->setRotation(core::vector3df(EulerRotation[0], EulerRotation[1], EulerRotation[2])); } } // Creates a base box void CreateStartScene(ISceneManager* smgr) { ClearObjects(); CreateBox(smgr,btVector3(0.0f, 0.0f, 0.0f), core::vector3df(10.0f, 0.5f, 10.0f), 0.0f); } int main(int argc, char *argv[]){ // Initialize bullet 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(); World = new btDiscreteDynamicsWorld(Dispatcher, BroadPhase, Solver, CollisionConfiguration); //Create a new lua state, this gets shared everywhere lua_State *state = luaL_newstate(); L = state; //Load the lua libraries loadLLibs(state); //Defined in initdevice.cpp, creates the irrlicht device device = spawnIrrDevice(state); if (!device) return 1; //Loads libraries for interfaceing with irrlicht loadIrrLibs(state,device); printf("Loadded irr libs...\n"); //Sets the global event handeler GlobalEventReceiver ger = GlobalEventReceiver(device); device->setEventReceiver(&ger); int iErr = luaL_dofile(state,"../data/guitest.lua"); if(iErr != 0){ lua_error(state); printf("Failed to open lua file:../data/guitest.lua\n"); } //Load some bullet physics stuff //Load some menu loadMenu("Some menu",device); IVideoDriver* driver = device->getVideoDriver(); ISceneManager* smgr = device->getSceneManager(); IGUIEnvironment* guienv = device->getGUIEnvironment(); ITimer* irrTimer = device->getTimer(); device->setWindowCaption(L"Bork[en]gine Demo"); /* CreateBox(smgr, btVector3( GetRandInt(10) - 5.0f, 7.0f, GetRandInt(10) - 5.0f), core::vector3df( GetRandInt(3) + 0.5f, GetRandInt(3) + 0.5f, GetRandInt(3) + 0.5f), 1.0f); CreateBox(smgr, btVector3(0,0,0), core::vector3df(10,10,10), 0.0f); CreateSphere(smgr, btVector3( GetRandInt(10) - 5.0f, 7.0f, GetRandInt(10) - 5.0f), GetRandInt(5) / 5.0f + 0.2f, 1.0f); */ guienv->addStaticText(L"Hello World! This is the Irrlicht Software renderer!", rect(10,10,260,22), true); smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0)); printf("Everything registered, about to start running device!\n"); u32 TimeStamp = irrTimer->getTime(), DeltaTime = 0; while(device->run()){ if(device->isWindowActive()){ DeltaTime = irrTimer->getTime() - TimeStamp; TimeStamp = irrTimer->getTime(); UpdatePhysics(DeltaTime); driver->beginScene(true, true, SColor(255,100,101,140)); smgr->drawAll(); guienv->drawAll(); driver->endScene(); }else{ device->yield(); } lua_getglobal(state,"GAME"); lua_getfield(state,-1,"tick"); if(!lua_isnil(state,-1)) lua_call(state,0,0); } printf("Claoseing lua state...\n"); //lua_close(state); printf("clearing objects...\n"); ClearObjects(); printf("cleared objects\n"); delete BroadPhase; printf("deleted broadphase\n"); delete CollisionConfiguration; printf("deleted collision config\n"); delete Dispatcher; printf("Deleted dispatcher\n"); delete Solver; printf("deleted solver\n"); delete World; //Muah ha ha printf("deleted world\n"); device->drop(); printf("droped device\n"); return 0; }