#include #include /* usleep() */ #include #include #ifdef _WIN32 #include /* Sleep() */ #endif #include /* INT_MAX */ #include #include #include #include "ag.h" #include "ag_lua.h" #include "anaglym.h" #include "Engine.h" #include "wfobj/WFObj.h" #include "AV.h" using namespace std; namespace ag { void register_functions(lua_State * L) { static const luaL_Reg functions[] = { { "callList", callList }, { "clearEventHandler", clearEventHandler }, { "doPhysics", doPhysics }, { "drawArc", drawArc }, { "drawCircle", drawCircle }, { "drawImage", drawImage }, { "drawLine", drawLine }, { "drawObjects", drawObjects }, { "drawPoint", drawPoint }, { "drawRect", drawRect }, { "drawText", drawText }, { "elapsedTime", elapsedTime }, { "endFrame", endFrame }, { "endList", endList }, { "exit", exit }, { "fillArc", fillArc }, { "fillCircle", fillCircle }, { "fillRect", fillRect }, { "getCamera", getCamera }, { "getCursorVisible", getCursorVisible }, { "getScreenSize", getScreenSize }, { "getTextSize", getTextSize }, { "import", import }, { "isKeyDown", isKeyDown }, { "loadModelSpecify", loadModelSpecify }, { "loadSound", loadSound }, { "loadTexture", loadTexture }, { "next", next }, { "pickObjects", pickObjects }, { "print", print }, { "println", println }, { "registerEventHandler", registerEventHandler }, { "setAutoDrawObjects", setAutoDrawObjects }, { "setAutoEndFrame", setAutoEndFrame }, { "setAutoPhysics", setAutoPhysics }, { "setAutoStartFrame", setAutoStartFrame }, { "setCamera", setCamera }, { "setCursorVisible", setCursorVisible }, { "setGravity", setGravity }, // { "sleep", sleep }, { "startFrame", startFrame }, { "startList", startList }, { "type", type }, { "clearWorld", clearWorld }, { "_createAMotor", _createAMotor }, { "_createHinge", _createHinge }, /* managed object functions */ { "createBoxSpecify", createBoxSpecify }, { "createCapsuleSpecify", createCapsuleSpecify }, { "createPlaneSpecify", createPlaneSpecify }, { "createSphereSpecify", createSphereSpecify }, { NULL, NULL } }; luaL_register(L, "ag", functions); ag_lua[ag_lua_len - 1] = '\0'; luaL_loadstring(L, (const char *) ag_lua); lua_pcall(L, 0, 0, 0); } int pickObjects(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_isnumber(L, 1) && lua_isnumber(L, 2)) { lua_newtable(L); int next_index = 1; refptr< vector > objects = g_engine->pickObjects(lua_tointeger(L, 1), lua_tointeger(L, 2)); for (vector::const_iterator it = objects->begin(); it != objects->end(); it++) { lua_getfield(L, LUA_GLOBALSINDEX, "ag");/* {ag} */ lua_getfield(L, -1, "_objects"); /* {ag,_objects} */ lua_pushinteger(L, (*it)->id); /* {ag,_objects,id} */ lua_gettable(L, -2); /* {ag,_objects,obj} */ lua_remove(L, -3); /* {_objects,obj} */ lua_remove(L, -2); /* {obj} */ if (!lua_isnil(L, -1)) { lua_pushinteger(L, next_index++); /* {obj,index} */ lua_pushvalue(L, -2); /* {obj,index,obj} */ lua_settable(L, argc + 1); /* {obj} */ } lua_pushstring(L, "pick_dist"); /* {obj,"pick_dist"} */ lua_pushnumber(L, (*it)->dist); /* {obj,"pick_dist",dist} */ lua_settable(L, -3); /* {obj} */ lua_createtable(L, 3, 0); /* {obj,arr} */ for (int i = 0; i < 3; i++) { lua_pushinteger(L, i + 1); /* {obj,arr,index} */ lua_pushnumber(L, (*it)->pos[i]);/* {obj,arr,index,pos_x} */ lua_settable(L, -3); /* {obj,arr} */ } lua_pushstring(L, "pick_pos"); /* {obj,arr,"pick_pos"} */ lua_pushvalue(L, -2); /* {obj,arr,"pick_pos",arr} */ lua_settable(L, -4); /* {obj,arr} */ lua_pop(L, 1); /* {obj} */ lua_createtable(L, 3, 0); /* {obj,arr} */ for (int i = 0; i < 3; i++) { lua_pushinteger(L, i + 1); /* {obj,arr,index} */ lua_pushnumber(L, (*it)->normal[i]);/* {obj,arr,index,n} */ lua_settable(L, -3); /* {obj,arr} */ } lua_pushstring(L, "pick_normal"); /* {obj,arr,"pick_normal"} */ lua_pushvalue(L, -2); /* {obj,arr,"pick_normal",arr} */ lua_settable(L, -4); /* {obj,arr} */ lua_pop(L, 1); /* {obj} */ lua_pop(L, 1); /* {} */ } } else { lua_pushnil(L); } return 1; } static void print_val(lua_State * L, int index) { int type = lua_type(L, index); switch (type) { case LUA_TNUMBER: cout << lua_tonumber(L, index); break; case LUA_TSTRING: cout << lua_tostring(L, index); break; case LUA_TTABLE: cout << "{ "; /* traverse the table and print the keys/values */ lua_checkstack(L, 3); lua_pushnil(L); for (bool first = true; lua_next(L, index) != 0; first = false) { if (!first) cout << ", "; cout << '['; print_val(L, lua_gettop(L) - 1); cout << ']'; cout << " => "; print_val(L, lua_gettop(L)); lua_pop(L, 1); } cout << " }"; break; case LUA_TFUNCTION: cout << ""; break; case LUA_TUSERDATA: cout << ""; break; case LUA_TTHREAD: cout << ""; break; case LUA_TLIGHTUSERDATA: cout << ""; break; } } int print(lua_State * L) { int argc = lua_gettop(L); for ( int n = 1; n <= argc; n++ ) { print_val(L, n); } return 0; } int println(lua_State * L) { int ret = print(L); cout << endl; return ret; } int next(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 || argc == 2) { if (argc == 1) { lua_pushnil(L); } else { lua_pushvalue(L, 2); } if (lua_next(L, 1) == 0) { lua_pushnil(L); return 1; } return 2; } else { lua_pushnil(L); return 1; } } int type(lua_State * L) { int argc = lua_gettop(L); if (argc == 1) { int type = lua_type(L, 1); switch (type) { case LUA_TNUMBER: lua_pushstring(L, "number"); break; case LUA_TBOOLEAN: lua_pushstring(L, "boolean"); break; case LUA_TSTRING: lua_pushstring(L, "string"); break; case LUA_TTABLE: lua_pushstring(L, "table"); break; case LUA_TFUNCTION: lua_pushstring(L, "function"); break; case LUA_TTHREAD: lua_pushstring(L, "thread"); break; case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: lua_pushstring(L, "userdata"); break; case LUA_TNIL: default: lua_pushstring(L, "nil"); break; } } else { lua_pushstring(L, "nil"); } return 1; } static void createLuaObject(lua_State * L, int id) { lua_newtable(L); lua_pushinteger(L, id); lua_setfield(L, -2, "id"); lua_pushcfunction(L, object::draw); lua_setfield(L, -2, "draw"); lua_pushcfunction(L, object::setPosition); lua_setfield(L, -2, "setPosition"); lua_pushcfunction(L, object::getPosition); lua_setfield(L, -2, "getPosition"); lua_pushcfunction(L, object::setRotation); lua_setfield(L, -2, "setRotation"); lua_pushcfunction(L, object::clone); lua_setfield(L, -2, "clone"); lua_pushcfunction(L, object::destroy); lua_setfield(L, -2, "destroy"); lua_pushcfunction(L, object::setVisible); lua_setfield(L, -2, "setVisible"); lua_pushcfunction(L, object::addForce); lua_setfield(L, -2, "addForce"); lua_pushcfunction(L, object::addForceRel); lua_setfield(L, -2, "addForceRel"); lua_pushcfunction(L, object::addTorque); lua_setfield(L, -2, "addTorque"); lua_pushcfunction(L, object::addTorqueRel); lua_setfield(L, -2, "addTorqueRel"); lua_pushcfunction(L, object::setColor); lua_setfield(L, -2, "setColor"); lua_pushcfunction(L, object::setGravityMode); lua_setfield(L, -2, "setGravityMode"); lua_pushcfunction(L, object::setTexture); lua_setfield(L, -2, "setTexture"); lua_pushcfunction(L, object::setTextureScale); lua_setfield(L, -2, "setTextureScale"); lua_pushcfunction(L, object::setMass); lua_setfield(L, -2, "setMass"); lua_pushcfunction(L, object::getMass); lua_setfield(L, -2, "getMass"); lua_pushcfunction(L, object::getAABB); lua_setfield(L, -2, "getAABB"); lua_pushcfunction(L, object::getSize); lua_setfield(L, -2, "getSize"); /* ag._objects[id] = obj */ lua_getfield(L, LUA_GLOBALSINDEX, "ag"); /* pushes 1 */ lua_getfield(L, -1, "_objects"); /* pushes 1 */ lua_pushinteger(L, id); /* pushes 1 */ lua_pushvalue(L, -4); /* pushes 1 */ lua_settable(L, -3); /* pops 2 */ lua_pop(L, 2); /* pops 2 */ } static void createLuaSound(lua_State * L, int id) { lua_newtable(L); lua_pushinteger(L, id); lua_setfield(L, -2, "id"); lua_pushcfunction(L, sound::play); lua_setfield(L, -2, "play"); lua_pushcfunction(L, sound::resume); lua_setfield(L, -2, "resume"); lua_pushcfunction(L, sound::stop); lua_setfield(L, -2, "stop"); lua_pushcfunction(L, sound::loop); lua_setfield(L, -2, "loop"); lua_pushcfunction(L, sound::loopForever); lua_setfield(L, -2, "loopForever"); lua_pushcfunction(L, sound::getVolume); lua_setfield(L, -2, "getVolume"); lua_pushcfunction(L, sound::setVolume); lua_setfield(L, -2, "setVolume"); } static void createLuaAMotor(lua_State * L, int id) { lua_newtable(L); lua_pushinteger(L, id); lua_setfield(L, -2, "id"); lua_pushcfunction(L, joint::setAMotorLoStop); lua_setfield(L, -2, "setLoStop"); lua_pushcfunction(L, joint::setAMotorHiStop); lua_setfield(L, -2, "setHiStop"); lua_pushcfunction(L, joint::setAMotorVel); lua_setfield(L, -2, "setVel"); lua_pushcfunction(L, joint::setAMotorFMax); lua_setfield(L, -2, "setFMax"); lua_pushcfunction(L, joint::setAMotorBounce); lua_setfield(L, -2, "setBounce"); lua_pushcfunction(L, joint::setAMotorAxis); lua_setfield(L, -2, "setAxis"); lua_pushcfunction(L, joint::setAMotorNumAxes); lua_setfield(L, -2, "setNumAxes"); lua_pushcfunction(L, joint::setAMotorAngle); lua_setfield(L, -2, "setAngle"); } static void createLuaHinge(lua_State * L, int id) { lua_newtable(L); lua_pushinteger(L, id); lua_setfield(L, -2, "id"); } int _createAMotor(lua_State * L) { int argc = lua_gettop(L); if (argc == 2) { Engine::Object * o1 = object::getObject(L, 1); Engine::Object * o2 = object::getObject(L, 2); /* it is ok if o1 or o2 are NULL, this means that the joint * is connected to the global environment */ if (o1 != NULL || o2 != NULL) { int jid = g_engine->addAMotor(o1, o2); if (jid != 0) { createLuaAMotor(L, jid); return 1; } } } lua_pushnil(L); return 1; } int _createHinge(lua_State * L) { int argc = lua_gettop(L); if (argc == 8 && lua_isnumber(L, 3) && lua_isnumber(L, 4) && lua_isnumber(L, 5) && lua_isnumber(L, 6) && lua_isnumber(L, 7) && lua_isnumber(L, 8)) { Engine::Object * o1 = object::getObject(L, 1); Engine::Object * o2 = object::getObject(L, 2); /* it is ok if o1 or o2 are NULL, this means that the joint * is connected to the global environment */ if (o1 != NULL || o2 != NULL) { int jid = g_engine->addHinge(o1, o2, lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), lua_tonumber(L, 8)); if (jid != 0) { createLuaHinge(L, jid); return 1; } } } lua_pushnil(L); return 1; } int loadModelSpecify(lua_State * L) { bool added = false; int argc = lua_gettop(L); if (argc == 4 && lua_isstring(L, 1) && lua_isnumber(L, 2) && lua_isboolean(L, 3) && lua_isboolean(L, 4)) { int id = g_engine->loadModel( lua_tostring(L, 1), /* name */ lua_toboolean(L, 3), /* static */ lua_toboolean(L, 4), /* reference */ lua_tonumber(L, 2)); /* scale */ if (id > 0) { createLuaObject(L, id); added = true; } } if (!added) lua_pushnil(L); return 1; } int loadSound(lua_State * L) { bool created = false; int argc = lua_gettop(L); if (argc == 1 && lua_isstring(L, 1)) { int id = g_engine->loadSound(lua_tostring(L, 1)); if (id > 0) { created = true; createLuaSound(L, id); } } if (!created) { lua_pushnil(L); } return 1; } int sleep(lua_State * L) { int argc = lua_gettop(L); if (argc == 1) { if (lua_isnumber(L, -1)) { double seconds = lua_tonumber(L, -1); #ifdef _WIN32 Sleep((DWORD)(seconds * 1000)); #else usleep((useconds_t) (seconds * 1000000)); #endif } } return 0; } int startFrame(lua_State * L) { g_engine->startFrame(); return 0; } int endFrame(lua_State * L) { g_engine->endFrame(); return 0; } int setCamera(lua_State * L) { return g_engine->setCamera(L); } int setCursorVisible(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_isboolean(L, 1)) { g_engine->setScriptCursorVisible(lua_toboolean(L, 1)); } return 0; } int setGravity(lua_State * L) { int argc = lua_gettop(L); if (argc == 3 && lua_isnumber(L, 1) && lua_isnumber(L, 2) && lua_isnumber(L, 3)) { g_engine->setGravity(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3)); } return 0; } int getCamera(lua_State * L) { return g_engine->getCamera(L); } int getCursorVisible(lua_State * L) { lua_pushboolean(L, g_engine->getScriptCursorVisible()); return 1; } int elapsedTime(lua_State * L) { lua_pushinteger(L, SDL_GetTicks()); return 1; } int doPhysics(lua_State * L) { g_engine->doPhysics(); return 0; } int drawObjects(lua_State * L) { g_engine->drawObjects(); return 0; } int setAutoPhysics(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_isboolean(L, 1)) g_engine->setAutoPhysics(lua_toboolean(L, 1)); return 0; } int setAutoStartFrame(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_isboolean(L, 1)) g_engine->setAutoStartFrame(lua_toboolean(L, 1)); return 0; } int setAutoEndFrame(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_isboolean(L, 1)) g_engine->setAutoEndFrame(lua_toboolean(L, 1)); return 0; } int setAutoDrawObjects(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_isboolean(L, 1)) g_engine->setAutoDrawObjects(lua_toboolean(L, 1)); return 0; } int isKeyDown(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_isstring(L, 1)) lua_pushboolean(L, g_engine->isKeyDown(lua_tostring(L, 1))); else lua_pushboolean(L, false); return 1; } int registerEventHandler(lua_State * L) { return g_engine->registerEventHandler(L); } int clearEventHandler(lua_State * L) { return g_engine->clearEventHandler(L); } int exit(lua_State * L) { g_engine->exit(); return 0; } int import(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_isstring(L, 1)) lua_pushboolean(L, g_engine->import(lua_tostring(L, 1))); else lua_pushnil(L); return 1; } int loadTexture(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_isstring(L, 1)) { GLuint texture; if ((texture = g_engine->loadTexture(lua_tostring(L, 1))) != 0) { lua_newtable(L); lua_pushinteger(L, texture); lua_setfield(L, -2, "id"); return 1; } } lua_pushnil(L); return 1; } int getScreenSize(lua_State * L) { int width, height; g_engine->getScreenSize(&width, &height); lua_pushinteger(L, width); lua_pushinteger(L, height); return 2; } int drawText(lua_State * L) { int argc = lua_gettop(L); if (argc == 7 && lua_isstring(L, 1) && lua_isnumber(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4) && lua_isnumber(L, 5) && lua_isnumber(L, 6) && lua_isnumber(L, 7)) { g_engine->drawText(lua_tostring(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tointeger(L, 5), lua_tointeger(L, 6), lua_tointeger(L, 7)); } return 0; } int getTextSize(lua_State * L) { float width = 0.0f; float height = 0.0f; int argc = lua_gettop(L); if (argc == 2 && lua_isstring(L, 1) && lua_isnumber(L, 2)) { g_engine->getTextSize(lua_tostring(L, 1), lua_tointeger(L, 2), &width, &height); } lua_pushnumber(L, width); lua_pushnumber(L, height); return 2; } int drawLine(lua_State * L) { int argc = lua_gettop(L); if (argc == 7 || argc == 8) { bool valid = true; for (int i = 1; i <= argc; i++) if (!lua_isnumber(L, i)) valid = false; if (valid) { float width = 1.0f; if (argc == 8) width = lua_tonumber(L, 8); g_engine->drawLine( lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), width); } } return 0; } int drawPoint(lua_State * L) { int argc = lua_gettop(L); if (argc == 6 || argc == 7) { bool valid = true; for (int i = 1; i <= argc; i++) if (!lua_isnumber(L, i)) valid = false; if (valid) { float z = 0.0f; if (argc == 7) z = lua_tonumber(L, 7); g_engine->drawPoint( lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), z); } } return 0; } int drawRect(lua_State * L) { int argc = lua_gettop(L); if (argc == 7 || argc == 8) { bool valid = true; for (int i = 1; i <= argc; i++) if (!lua_isnumber(L, i)) valid = false; if (valid) { float rot = 0.0f; if (argc == 8) rot = lua_tonumber(L, 8); g_engine->drawRect( lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), rot); } } return 0; } int fillArc(lua_State * L) { int argc = lua_gettop(L); if (argc == 8) { bool valid = true; for (int i = 1; i <= argc; i++) { if (!lua_isnumber(L, i)) valid = false; } if (valid) { g_engine->fillArc( lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), lua_tonumber(L, 8)); } } return 0; } int fillCircle(lua_State * L) { int argc = lua_gettop(L); if (argc == 6) { bool valid = true; for (int i = 1; i <= argc; i++) { if (!lua_isnumber(L, i)) valid = false; } if (valid) { g_engine->fillArc( lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), 0.0, 360.0); } } return 0; } int fillRect(lua_State * L) { int argc = lua_gettop(L); if (argc == 7 || argc == 8) { bool valid = true; for (int i = 1; i <= argc; i++) if (!lua_isnumber(L, i)) valid = false; if (valid) { float rot = 0.0f; if (argc == 8) rot = lua_tonumber(L, 8); g_engine->fillRect( lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), rot); } } return 0; } int drawArc(lua_State * L) { int argc = lua_gettop(L); if (argc == 8) { bool valid = true; for (int i = 1; i <= argc; i++) { if (!lua_isnumber(L, i)) valid = false; } if (valid) { g_engine->drawArc( lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), lua_tonumber(L, 7), lua_tonumber(L, 8)); } } return 0; } int drawCircle(lua_State * L) { int argc = lua_gettop(L); if (argc == 6) { bool valid = true; for (int i = 1; i <= argc; i++) { if (!lua_isnumber(L, i)) valid = false; } if (valid) { g_engine->drawArc( lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6), 0.0, 360.0); } } return 0; } int drawImage(lua_State * L) { int argc = lua_gettop(L); if (argc == 5 || argc == 6) { bool valid = true; for (int i = 1; i <= argc; i++) if (i != 5 && !lua_isnumber(L, i)) valid = false; if (!lua_istable(L, 5)) valid = false; if (valid) { lua_getfield(L, 5, "id"); if (lua_isnumber(L, -1)) { float rot = 0.0f; if (argc == 6) rot = lua_tonumber(L, 6); GLuint texture_id = (GLuint) lua_tointeger(L, -1); g_engine->drawImage( lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4), texture_id, rot); } lua_pop(L, 1); } } return 0; } static void addManagedObject(lua_State * L, bool is_static, bool is_reference, OdeWorld::GeomType geom_type, refptr< vector > args) { int id = g_engine->addObject(is_static, is_reference, geom_type, args); createLuaObject(L, id); } int createBoxSpecify(lua_State * L) { int argc = lua_gettop(L); if (argc == 5 && lua_isnumber(L, 1) && lua_isnumber(L, 2) && lua_isnumber(L, 3) && lua_isboolean(L, 4) && lua_isboolean(L, 5)) { refptr< vector > args = new vector(); for (int i = 1; i <= 3; i++) args->push_back(lua_tonumber(L, i)); addManagedObject(L, lua_toboolean(L, 4), lua_toboolean(L, 5), OdeWorld::BOX, args); } else lua_pushnil(L); return 1; } int createSphereSpecify(lua_State * L) { int argc = lua_gettop(L); if (argc == 3 && lua_isnumber(L, 1) && lua_isboolean(L, 2) && lua_isboolean(L, 3)) { refptr< vector > args = new vector(); args->push_back(lua_tonumber(L, 1)); addManagedObject(L, lua_toboolean(L, 2), lua_toboolean(L, 3), OdeWorld::SPHERE, args); } else lua_pushnil(L); return 1; } int createPlaneSpecify(lua_State * L) { int argc = lua_gettop(L); if (argc == 5 || argc == 7) { bool valid = lua_isboolean(L, argc); for (int i = 1; i < argc; i++) { if (!lua_isnumber(L, i)) { valid = false; break; } } if (valid) { refptr< vector > args = new vector(); for (int i = 1; i < argc; i++) args->push_back(lua_tonumber(L, i)); addManagedObject(L, true, lua_toboolean(L, argc), OdeWorld::PLANE, args); return 1; } } lua_pushnil(L); return 1; } int createCylinderSpecify(lua_State * L) { int argc = lua_gettop(L); if (argc == 4 && lua_isnumber(L, 1) && lua_isnumber(L, 2) && lua_isboolean(L, 3) && lua_isboolean(L, 4)) { refptr< vector > args = new vector(); args->push_back(lua_tonumber(L, 1)); args->push_back(lua_tonumber(L, 2)); addManagedObject(L, lua_toboolean(L, 3), lua_toboolean(L, 4), OdeWorld::CYLINDER, args); } else lua_pushnil(L); return 1; } int createCapsuleSpecify(lua_State * L) { int argc = lua_gettop(L); if (argc == 4 && lua_isnumber(L, 1) && lua_isnumber(L, 2) && lua_isboolean(L, 3) && lua_isboolean(L, 4)) { refptr< vector > args = new vector(); args->push_back(lua_tonumber(L, 1)); args->push_back(lua_tonumber(L, 2)); addManagedObject(L, lua_toboolean(L, 3), lua_toboolean(L, 4), OdeWorld::CAPSULE, args); } else lua_pushnil(L); return 1; } int startList(lua_State * L) { GLuint list = g_engine->startList(); lua_pushnumber(L, list); return 1; } int clearWorld(lua_State * L) { g_engine->clearWorld(); return 0; } int endList(lua_State * L) { g_engine->endList(); return 0; } int callList(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_isnumber(L, 1)) { g_engine->callList(lua_tointeger(L, 1)); } return 0; } namespace object { Engine::Object * getObject(lua_State * L, int index) { Engine::Object * ret = NULL; lua_getfield(L, index, "id"); if (lua_isnumber(L, -1)) { int id = lua_tointeger(L, -1); ret = g_engine->getObject(id); } lua_pop(L, 1); return ret; } int draw(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_istable(L, -1)) { Engine::Object * obj = getObject(L, -1); if (obj != NULL) obj->draw(); } return 0; } int setPosition(lua_State * L) { int argc = lua_gettop(L); if (argc == 4) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { double position[3]; for (int i = 0; i < 3; i++) { position[i] = (lua_isnumber(L, i + 2)) ? lua_tonumber(L, i + 2) : 0.0; } obj->setPosition(position[0], position[1], position[2]); } } return 0; } int getPosition(lua_State * L) { int argc = lua_gettop(L); if (argc == 1) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { double x, y, z; obj->getPosition(&x, &y, &z); lua_pushnumber(L, x); lua_pushnumber(L, y); lua_pushnumber(L, z); return 3; } } return 0; } int setRotation(lua_State * L) { int argc = lua_gettop(L); if (argc == 4) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { double rot[3]; for (int i = 0; i < 3; i++) { rot[i] = (lua_isnumber(L, i + 2)) ? lua_tonumber(L, i + 2) : 0.0; } obj->setRotation(rot[0], rot[1], rot[2]); } } return 0; } int clone(lua_State * L) { int argc = lua_gettop(L); bool found = false; if (argc == 1) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { found = true; int id = g_engine->cloneObject(obj); createLuaObject(L, id); } } if (!found) lua_pushnil(L); return 1; } static void clearLuaTable(lua_State * L, int index) { lua_pushnil(L); /* * lua_next pops the key from the stack * it pushes the key, value pair if there is one */ while (lua_next(L, index) != 0) { lua_pop(L, 1); /* pop old value */ lua_pushvalue(L, -1); /* duplicate the key */ lua_pushnil(L); lua_settable(L, index); /* set table[key] = nil */ } } int destroy(lua_State * L) { int argc = lua_gettop(L); if (argc == 1) { lua_getfield(L, 1, "id"); if (lua_isnumber(L, -1)) { int id = lua_tointeger(L, -1); g_engine->removeObject(id); /* ag._objects[id] = nil */ lua_getfield(L, LUA_GLOBALSINDEX, "ag"); /* pushes 1 */ lua_getfield(L, -1, "_objects"); /* pushes 1 */ lua_pushinteger(L, id); /* pushes 1 */ lua_pushnil(L); /* pushes 1 */ lua_settable(L, -3); /* pops 2 */ lua_pop(L, 2); /* pops 2 */ } lua_pop(L, 1); clearLuaTable(L, 1); } return 0; } int setVisible(lua_State * L) { int argc = lua_gettop(L); if (argc == 2) { Engine::Object * obj = getObject(L, 1); if (obj != NULL && lua_isboolean(L, 2)) { obj->setVisible(lua_toboolean(L, 2)); } } return 0; } int addForce(lua_State * L) { int argc = lua_gettop(L); if (argc == 4) { Engine::Object * obj = getObject(L, 1); if (obj != NULL && lua_isnumber(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) { obj->addForce(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4)); } } return 0; } int addForceRel(lua_State * L) { int argc = lua_gettop(L); if (argc == 4) { Engine::Object * obj = getObject(L, 1); if (obj != NULL && lua_isnumber(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) { obj->addForceRel(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4)); } } return 0; } int addTorque(lua_State * L) { int argc = lua_gettop(L); if (argc == 4) { Engine::Object * obj = getObject(L, 1); if (obj != NULL && lua_isnumber(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) { obj->addTorque(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4)); } } return 0; } int addTorqueRel(lua_State * L) { int argc = lua_gettop(L); if (argc == 4) { Engine::Object * obj = getObject(L, 1); if (obj != NULL && lua_isnumber(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) { obj->addTorqueRel(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4)); } } return 0; } int setColor(lua_State * L) { int argc = lua_gettop(L); if (argc == 4 && lua_isnumber(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4)) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { obj->setColor(lua_tonumber(L, 2), lua_tonumber(L, 3), lua_tonumber(L, 4)); } } return 0; } int setGravityMode(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_isboolean(L, 2)) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { obj->setGravityMode(lua_toboolean(L, 2)); } } return 0; } int setTexture(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_istable(L, 2)) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { lua_getfield(L, 2, "id"); if (lua_isnumber(L, -1)) { GLuint id = (GLuint) lua_tointeger(L, -1); obj->setTexture(id); } lua_pop(L, 1); } } return 0; } int setTextureScale(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { obj->setTextureScale(lua_tonumber(L, 2)); } } return 0; } int getMass(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_istable(L, 1)) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { lua_pushnumber(L, obj->getMass()); return 1; } } lua_pushnumber(L, 0); return 1; } int setMass(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { obj->setMass(lua_tonumber(L, 2)); } } return 0; } int getAABB(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_istable(L, 1)) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { const float * aabb = obj->getAABB(); for (int i = 0; i < 6; i++) { lua_pushnumber(L, aabb[i]); } return 6; } } lua_pushnil(L); return 1; } int getSize(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_istable(L, 1)) { Engine::Object * obj = getObject(L, 1); if (obj != NULL) { const float * aabb = obj->getAABB(); for (int i = 0; i < 3; i++) { lua_pushnumber(L, aabb[i+3] - aabb[i]); } return 3; } } lua_pushnil(L); return 1; } } namespace joint { int setAMotorAxis(lua_State * L) { int argc = lua_gettop(L); if (argc == 6 && lua_istable(L, 1) && lua_isnumber(L, 2) && lua_isnumber(L, 3) && lua_isnumber(L, 4) && lua_isnumber(L, 5) && lua_isnumber(L, 6)) { lua_getfield(L, 1, "id"); if (lua_isnumber(L, -1)) { int jid = lua_tointeger(L, -1); g_engine->setAMotorAxis(jid, lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6)); } lua_pop(L, 1); } return 0; } int setAMotorNumAxes(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { lua_getfield(L, 1, "id"); if (lua_isnumber(L, -1)) { int jid = lua_tointeger(L, -1); g_engine->setAMotorNumAxes(jid, lua_tointeger(L, 2)); } lua_pop(L, 1); } return 0; } int setAMotorAngle(lua_State * L) { int argc = lua_gettop(L); if (argc == 3 && lua_istable(L, 1) && lua_isnumber(L, 2) && lua_isnumber(L, 3)) { lua_getfield(L, 1, "id"); if (lua_isnumber(L, -1)) { int jid = lua_tointeger(L, -1); g_engine->setAMotorAngle(jid, lua_tointeger(L, 2), lua_tonumber(L, 3)); } lua_pop(L, 1); } return 0; } int setAMotorLoStop(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { lua_getfield(L, 1, "id"); if (lua_isnumber(L, -1)) { int jid = lua_tointeger(L, -1); g_engine->setAMotorLoStop(jid, lua_tonumber(L, 2)); } lua_pop(L, 1); } return 0; } int setAMotorHiStop(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { lua_getfield(L, 1, "id"); if (lua_isnumber(L, -1)) { int jid = lua_tointeger(L, -1); g_engine->setAMotorHiStop(jid, lua_tonumber(L, 2)); } lua_pop(L, 1); } return 0; } int setAMotorVel(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { lua_getfield(L, 1, "id"); if (lua_isnumber(L, -1)) { int jid = lua_tointeger(L, -1); g_engine->setAMotorVel(jid, lua_tonumber(L, 2)); } lua_pop(L, 1); } return 0; } int setAMotorFMax(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { lua_getfield(L, 1, "id"); if (lua_isnumber(L, -1)) { int jid = lua_tointeger(L, -1); g_engine->setAMotorFMax(jid, lua_tonumber(L, 2)); } lua_pop(L, 1); } return 0; } int setAMotorBounce(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { lua_getfield(L, 1, "id"); if (lua_isnumber(L, -1)) { int jid = lua_tointeger(L, -1); g_engine->setAMotorBounce(jid, lua_tonumber(L, 2)); } lua_pop(L, 1); } return 0; } } namespace sound { refptr getSound(lua_State * L, int index) { refptr ret; lua_getfield(L, index, "id"); if (lua_isnumber(L, -1)) { int id = lua_tointeger(L, -1); ret = g_engine->getSound(id); } lua_pop(L, 1); return ret; } int play(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_istable(L, 1)) { refptr snd = getSound(L, 1); if (!snd.isNull()) { snd->play(); } } return 0; } int resume(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_istable(L, 1)) { refptr snd = getSound(L, 1); if (!snd.isNull()) { snd->resume(); } } return 0; } int stop(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_istable(L, 1)) { refptr snd = getSound(L, 1); if (!snd.isNull()) { snd->stop(); } } return 0; } int loop(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { refptr snd = getSound(L, 1); if (!snd.isNull()) { int count = lua_tointeger(L, 2); snd->loop(count); } } return 0; } int loopForever(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_istable(L, 1)) { refptr snd = getSound(L, 1); if (!snd.isNull()) { snd->loop(INT_MAX); } } return 0; } int getVolume(lua_State * L) { int argc = lua_gettop(L); if (argc == 1 && lua_istable(L, 1)) { refptr snd = getSound(L, 1); if (!snd.isNull()) { float v = snd->getVolume(); lua_pushnumber(L, v); return 1; } } return 0; } int setVolume(lua_State * L) { int argc = lua_gettop(L); if (argc == 2 && lua_istable(L, 1) && lua_isnumber(L, 2)) { refptr snd = getSound(L, 1); if (!snd.isNull()) { float volume = lua_tonumber(L, 2); snd->setVolume(volume); } } return 0; } } }