#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; printf("Found an object to clean:%p\n",Object); // Delete irrlicht node ISceneNode *Node = static_cast(Object->getUserPointer()); printf("got node\n"); Node->remove(); printf("removed node\n"); // Remove the object from the world World->removeRigidBody(Object); printf("removed rigidbody\n"); printf("right before delete, object is %p\n",Object); delete Object; printf("deleted object\n"); } 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.002f, 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[]){ printf("Brok[en]gine"); // Initialize bullet btBroadphaseInterface *BroadPhase = new btAxisSweep3(btVector3(-1000, -1000, -1000), btVector3(1000, 1000, 1000)); printf("Broadphase\n"); btDefaultCollisionConfiguration *CollisionConfiguration = new btDefaultCollisionConfiguration(); printf("Collision config\n"); btCollisionDispatcher *Dispatcher = new btCollisionDispatcher(CollisionConfiguration); printf("Dispatcher\n"); btSequentialImpulseConstraintSolver *Solver = new btSequentialImpulseConstraintSolver(); printf("Solver\n"); World = new btDiscreteDynamicsWorld(Dispatcher, BroadPhase, Solver, CollisionConfiguration); printf("Physics world init ok.\n"); //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); printf("Abbout to add camera\n"); //smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0)); //smgr->addCameraSceneNodeMaya(); 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); lua_pop(state,2); } printf("Claoseing lua state...\n"); //lua_close(state); printf("clearing objects...\n"); ClearObjects(); //Clearing objects must be done after we droped the device. 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; }