| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- #include "LuaPhysicsSetup.h"
- #include "../CommonInterfaces/CommonMultiBodyBase.h"
- #include "../Importers/ImportURDFDemo/BulletURDFImporter.h"
- #include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
- #include "../Importers/ImportURDFDemo/URDF2Bullet.h"
- struct LuaPhysicsSetup : public CommonMultiBodyBase
- {
- LuaPhysicsSetup(GUIHelperInterface* helper);
- virtual ~LuaPhysicsSetup();
- virtual void initPhysics();
- virtual void exitPhysics();
- virtual void stepSimulation(float deltaTime)
- {
- m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
- CommonMultiBodyBase::stepSimulation(deltaTime);
- }
- };
- #include "btBulletDynamicsCommon.h"
- #include "LinearMath/btVector3.h"
- #include <iostream>
- extern "C"
- {
- #include "lua.h"
- #include "lualib.h"
- #include "lauxlib.h"
- }
- const char* sLuaFileName = "init_physics.lua";
- static int upaxis = 1;
- //const char* sLuaFileName = "init_urdf.lua";
- //static int upaxis = 2;
- static const float scaling = 0.35f;
- static LuaPhysicsSetup* sLuaDemo = 0;
- static btVector4 colors[4] =
- {
- btVector4(1, 0, 0, 1),
- btVector4(0, 1, 0, 1),
- btVector4(0, 1, 1, 1),
- btVector4(1, 1, 0, 1),
- };
- LuaPhysicsSetup::LuaPhysicsSetup(GUIHelperInterface* helper)
- : CommonMultiBodyBase(helper)
- {
- sLuaDemo = this;
- }
- LuaPhysicsSetup::~LuaPhysicsSetup()
- {
- sLuaDemo = 0;
- }
- //todo: allow to create solver, broadphase, multiple worlds etc.
- static int gCreateDefaultDynamicsWorld(lua_State* L)
- {
- sLuaDemo->createEmptyDynamicsWorld();
- btVector3 grav(0, 0, 0);
- grav[upaxis] = -10;
- sLuaDemo->m_dynamicsWorld->setGravity(grav);
- sLuaDemo->m_guiHelper->createPhysicsDebugDrawer(sLuaDemo->m_dynamicsWorld);
- lua_pushlightuserdata(L, sLuaDemo->m_dynamicsWorld);
- return 1;
- }
- static int gDeleteDynamicsWorld(lua_State* L)
- {
- return 0;
- }
- ATTRIBUTE_ALIGNED16(struct)
- CustomRigidBodyData
- {
- int m_graphicsInstanceIndex;
- };
- static int gCreateCubeShape(lua_State* L)
- {
- int argc = lua_gettop(L);
- if (argc == 4)
- {
- btVector3 halfExtents(1, 1, 1);
- if (!lua_isuserdata(L, 1))
- {
- std::cerr << "error: first argument to createCubeShape should be world";
- return 0;
- }
- //expect userdata = sLuaDemo->m_dynamicsWorld
- halfExtents = btVector3(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4));
- btCollisionShape* colShape = new btBoxShape(halfExtents);
- lua_pushlightuserdata(L, colShape);
- return 1;
- }
- else
- {
- std::cerr << "Error: invalid number of arguments to createCubeShape, expected 4 (world,halfExtentsX,halfExtentsY,halfExtentsX) but got " << argc;
- }
- return 0;
- }
- static int gCreateSphereShape(lua_State* L)
- {
- int argc = lua_gettop(L);
- if (argc == 2)
- {
- btVector3 halfExtents(1, 1, 1);
- if (!lua_isuserdata(L, 1))
- {
- std::cerr << "error: first argument to createSphereShape should be world";
- return 0;
- }
- //expect userdata = sLuaDemo->m_dynamicsWorld
- btScalar radius = lua_tonumber(L, 2);
- btCollisionShape* colShape = new btSphereShape(radius);
- lua_pushlightuserdata(L, colShape);
- return 1;
- }
- else
- {
- std::cerr << "Error: invalid number of arguments to createSphereShape, expected 2 (world,radius) but got " << argc;
- }
- return 0;
- }
- int luaL_returnlen(lua_State* L, int index)
- {
- lua_len(L, index);
- int len = lua_tointeger(L, -1);
- lua_pop(L, 1);
- return len;
- }
- btVector3 getLuaVectorArg(lua_State* L, int index)
- {
- btVector3 pos(0, 0, 0);
- int sz = luaL_returnlen(L, index); // get size of table
- {
- lua_rawgeti(L, index, 1); // push t[i]
- pos[0] = lua_tonumber(L, -1);
- lua_pop(L, 1);
- lua_rawgeti(L, index, 2); // push t[i]
- pos[1] = lua_tonumber(L, -1);
- lua_pop(L, 1);
- lua_rawgeti(L, index, 3); // push t[i]
- pos[2] = lua_tonumber(L, -1);
- lua_pop(L, 1);
- }
- return pos;
- }
- btQuaternion getLuaQuaternionArg(lua_State* L, int index)
- {
- btQuaternion orn(0, 0, 0, 1);
- int sz = luaL_returnlen(L, index); // get size of table
- {
- lua_rawgeti(L, index, 1); // push t[i]
- orn[0] = lua_tonumber(L, -1);
- lua_pop(L, 1);
- lua_rawgeti(L, index, 2); // push t[i]
- orn[1] = lua_tonumber(L, -1);
- lua_pop(L, 1);
- lua_rawgeti(L, index, 3); // push t[i]
- orn[2] = lua_tonumber(L, -1);
- lua_pop(L, 1);
- lua_rawgeti(L, index, 4); // push t[i]
- orn[3] = lua_tonumber(L, -1);
- lua_pop(L, 1);
- }
- return orn;
- }
- static int gLoadMultiBodyFromUrdf(lua_State* L)
- {
- int argc = lua_gettop(L);
- if (argc == 4)
- {
- if (!lua_isuserdata(L, 1))
- {
- std::cerr << "error: first argument to b3CreateRigidbody should be world";
- return 0;
- }
- luaL_checktype(L, 3, LUA_TTABLE);
- btVector3 pos = getLuaVectorArg(L, 3);
- btQuaternion orn = getLuaQuaternionArg(L, 4);
- btDiscreteDynamicsWorld* world = (btDiscreteDynamicsWorld*)lua_touserdata(L, 1);
- if (world != sLuaDemo->m_dynamicsWorld)
- {
- std::cerr << "error: first argument expected to be a world";
- return 0;
- }
- const char* fileName = lua_tostring(L, 2);
- #if 1
- BulletURDFImporter u2b(sLuaDemo->m_guiHelper, 0);
- bool loadOk = u2b.loadURDF(fileName);
- if (loadOk)
- {
- b3Printf("loaded %s OK!", fileName);
- btTransform tr;
- tr.setIdentity();
- tr.setOrigin(pos);
- tr.setRotation(orn);
- int rootLinkIndex = u2b.getRootLinkIndex();
- // printf("urdf root link index = %d\n",rootLinkIndex);
- MyMultiBodyCreator creation(sLuaDemo->m_guiHelper);
- bool m_useMultiBody = true;
- ConvertURDF2Bullet(u2b, creation, tr, sLuaDemo->m_dynamicsWorld, m_useMultiBody, u2b.getPathPrefix());
- btMultiBody* mb = creation.getBulletMultiBody();
- if (mb)
- {
- lua_pushlightuserdata(L, mb);
- return 1;
- }
- }
- else
- {
- b3Printf("can't find %s", fileName);
- }
- #endif
- }
- return 0;
- }
- static int gCreateRigidBody(lua_State* L)
- {
- int argc = lua_gettop(L);
- if (argc == 5)
- {
- btTransform startTransform;
- startTransform.setIdentity();
- if (!lua_isuserdata(L, 1))
- {
- std::cerr << "error: first argument to b3CreateRigidbody should be world";
- return 0;
- }
- btDiscreteDynamicsWorld* world = (btDiscreteDynamicsWorld*)lua_touserdata(L, 1);
- if (world != sLuaDemo->m_dynamicsWorld)
- {
- std::cerr << "error: first argument expected to be a world";
- return 0;
- }
- if (!lua_isuserdata(L, 2))
- {
- std::cerr << "error: second argument to b3CreateRigidbody should be collision shape";
- return 0;
- }
- btScalar mass = lua_tonumber(L, 3);
- luaL_checktype(L, 4, LUA_TTABLE);
- btVector3 pos = getLuaVectorArg(L, 4);
- btQuaternion orn = getLuaQuaternionArg(L, 5);
- btCollisionShape* colShape = (btCollisionShape*)lua_touserdata(L, 2);
- //expect userdata = sLuaDemo->m_dynamicsWorld
- btVector3 inertia(0, 0, 0);
- if (mass)
- {
- colShape->calculateLocalInertia(mass, inertia);
- }
- btRigidBody* body = new btRigidBody(mass, 0, colShape, inertia);
- body->getWorldTransform().setOrigin(pos);
- body->getWorldTransform().setRotation(orn);
- world->addRigidBody(body);
- lua_pushlightuserdata(L, body);
- return 1;
- }
- else
- {
- std::cerr << "Error: invalid number of arguments to createRigidBody, expected 5 (world,shape,mass,pos,orn) but got " << argc;
- }
- return 0;
- }
- static int gSetBodyPosition(lua_State* L)
- {
- int argc = lua_gettop(L);
- if (argc == 3)
- {
- if (!lua_isuserdata(L, 1))
- {
- std::cerr << "error: first argument needs to be a world";
- return 0;
- }
- if (!lua_isuserdata(L, 2))
- {
- std::cerr << "error: second argument needs to be a body";
- return 0;
- }
- btRigidBody* body = (btRigidBody*)lua_touserdata(L, 2);
- btVector3 pos = getLuaVectorArg(L, 3);
- btTransform& tr = body->getWorldTransform();
- tr.setOrigin(pos);
- body->setWorldTransform(tr);
- }
- else
- {
- std::cerr << "error: setBodyPosition expects 6 arguments like setBodyPosition(world,body,0,1,0)";
- }
- return 0;
- }
- static int gSetBodyOrientation(lua_State* L)
- {
- int argc = lua_gettop(L);
- if (argc == 3)
- {
- if (!lua_isuserdata(L, 1))
- {
- std::cerr << "error: first argument needs to be a world";
- return 0;
- }
- if (!lua_isuserdata(L, 2))
- {
- std::cerr << "error: second argument needs to be a body";
- return 0;
- }
- btRigidBody* body = (btRigidBody*)lua_touserdata(L, 2);
- btQuaternion orn = getLuaQuaternionArg(L, 3);
- btTransform& tr = body->getWorldTransform();
- tr.setRotation(orn);
- body->setWorldTransform(tr);
- }
- else
- {
- std::cerr << "error: setBodyOrientation expects 3 arguments like setBodyOrientation(world,body,orn)";
- }
- return 0;
- }
- //b3CreateConvexShape(world, points)
- //b3CreateHingeConstraint(world,bodyA,bodyB,...)
- static void report_errors(lua_State* L, int status)
- {
- if (status != 0)
- {
- std::cerr << "-- " << lua_tostring(L, -1) << std::endl;
- lua_pop(L, 1); // remove error message
- }
- }
- void LuaPhysicsSetup::initPhysics()
- {
- m_guiHelper->setUpAxis(upaxis);
- const char* prefix[] = {"./", "./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"};
- int numPrefixes = sizeof(prefix) / sizeof(const char*);
- char relativeFileName[1024];
- FILE* f = 0;
- int result = 0;
- for (int i = 0; !f && i < numPrefixes; i++)
- {
- sprintf(relativeFileName, "%s%s", prefix[i], sLuaFileName);
- f = fopen(relativeFileName, "rb");
- }
- if (f)
- {
- fclose(f);
- lua_State* L = luaL_newstate();
- luaopen_io(L); // provides io.*
- luaopen_base(L);
- luaopen_table(L);
- luaopen_string(L);
- luaopen_math(L);
- //luaopen_package(L);
- luaL_openlibs(L);
- // make my_function() available to Lua programs
- lua_register(L, "createDefaultDynamicsWorld", gCreateDefaultDynamicsWorld);
- lua_register(L, "deleteDynamicsWorld", gDeleteDynamicsWorld);
- lua_register(L, "createCubeShape", gCreateCubeShape);
- lua_register(L, "createSphereShape", gCreateSphereShape);
- lua_register(L, "loadMultiBodyFromUrdf", gLoadMultiBodyFromUrdf);
- lua_register(L, "createRigidBody", gCreateRigidBody);
- lua_register(L, "setBodyPosition", gSetBodyPosition);
- lua_register(L, "setBodyOrientation", gSetBodyOrientation);
- int s = luaL_loadfile(L, relativeFileName);
- if (s == 0)
- {
- // execute Lua program
- s = lua_pcall(L, 0, LUA_MULTRET, 0);
- }
- report_errors(L, s);
- lua_close(L);
- }
- else
- {
- b3Error("Cannot find Lua file%s\n", sLuaFileName);
- }
- }
- void LuaPhysicsSetup::exitPhysics()
- {
- CommonMultiBodyBase::exitPhysics();
- }
- class CommonExampleInterface* LuaDemoCreateFunc(struct CommonExampleOptions& options)
- {
- return new LuaPhysicsSetup(options.m_guiHelper);
- }
|