From 43cb1b3a418d8de68d669e7fec7bda0e8b498aba Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Sep 2013 17:27:49 +0000 Subject: [PATCH] Initial cut of setting and getting osg::Object properties within Lua scripts --- examples/osgpresentation/osgpresentation.cpp | 5 +- src/osgPlugins/lua/LuaScriptEngine.cpp | 408 ++++++++++++++++++- src/osgPlugins/lua/LuaScriptEngine.h | 5 +- 3 files changed, 405 insertions(+), 13 deletions(-) diff --git a/examples/osgpresentation/osgpresentation.cpp b/examples/osgpresentation/osgpresentation.cpp index c5475bafc..392db927b 100644 --- a/examples/osgpresentation/osgpresentation.cpp +++ b/examples/osgpresentation/osgpresentation.cpp @@ -425,6 +425,9 @@ int main(int argc, char** argv) } #endif + osg::Vec3f pos(1.5,3.0,4.5); + presentation->setProperty("position",pos); + osg::ref_ptr luaScriptEngine = osgDB::readFile("ScriptEngine.lua"); if (luaScriptEngine.valid()) { @@ -435,7 +438,7 @@ int main(int argc, char** argv) osg::ref_ptr script = osgDB::readFile(str); if (script.valid()) { - presentation->addUpdateCallback(new osg::ScriptCallback(script.get(),"doStuff")); + presentation->addUpdateCallback(new osg::ScriptCallback(script.get(),"update")); } } diff --git a/src/osgPlugins/lua/LuaScriptEngine.cpp b/src/osgPlugins/lua/LuaScriptEngine.cpp index 9d9d3c60e..96269a5bc 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.cpp +++ b/src/osgPlugins/lua/LuaScriptEngine.cpp @@ -12,10 +12,71 @@ */ #include "LuaScriptEngine.h" + #include using namespace lua; +static int getProperty(lua_State * _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + + int n = lua_gettop(_lua); /* number of arguments */ + if (n==2) + { + if (lua_type(_lua, 1)==LUA_TTABLE && + lua_type(_lua, 2)==LUA_TSTRING) + { + std::string propertyName = lua_tostring(_lua, 2); + + osg::Object* object = 0; + lua_pushstring(_lua, "object_ptr"); + lua_rawget(_lua, 1); + if (lua_type(_lua, -1)==LUA_TLIGHTUSERDATA) + { + object = const_cast(reinterpret_cast(lua_topointer(_lua,-1))); + } + lua_pop(_lua,1); + + return lse->pushPropertyToStack(object, propertyName); + } + } + + OSG_NOTICE<<"Warning: Lua getProperty() not matched"<(lua_topointer(_lua, lua_upvalueindex(1))); + + int n = lua_gettop(_lua); /* number of arguments */ + if (n==3) + { + if (lua_type(_lua, 1)==LUA_TTABLE && + lua_type(_lua, 2)==LUA_TSTRING) + { + std::string propertyName = lua_tostring(_lua, 2); + + osg::Object* object = 0; + lua_pushstring(_lua, "object_ptr"); + lua_rawget(_lua, 1); + if (lua_type(_lua, -1)==LUA_TLIGHTUSERDATA) + { + object = const_cast(reinterpret_cast(lua_topointer(_lua,-1))); + } + lua_pop(_lua,1); + + return lse->setPropertyFromStack(object, propertyName); + } + } + + OSG_NOTICE<<"Warning: Lua getProperty() not matched"<getScript().c_str()); if (loadResult==0) { - OSG_NOTICE<<"Loaded script"<get()); } - if (lua_pcall(_lua, inputParameters.size(), outputParameters.size(),0)!=0) { OSG_NOTICE<<"Lua error : "<get()); } + return true; } return false; @@ -295,11 +366,321 @@ public: virtual void apply(osg::Matrixd& value) { getMatrix(value); } }; +int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& propertyName) const +{ + osgDB::BaseSerializer::Type type; + if (!_pi.getPropertyType(object, propertyName, type)) + { + OSG_NOTICE<<"LuaScriptEngine::pushPropertyToStack("<(lua_toboolean(_lua, -1)!=0)); + return 0; + } + case(LUA_TNUMBER): + { + _pi.setProperty(object, propertyName, lua_tonumber(_lua, -1)); + return 0; + } + case(LUA_TSTRING): + { + _pi.setProperty(object, propertyName, std::string(lua_tostring(_lua, -1))); + return 0; + } + case(LUA_TTABLE): + { + typedef std::pair TypePair; + typedef std::vector< TypePair > Types; + Types types; + int n = lua_gettop(_lua); /* number of arguments */ + lua_pushnil(_lua); + while (lua_next(_lua, n) != 0) + { + types.push_back( TypePair( lua_type(_lua, -2), lua_type(_lua, -1) ) ); + lua_pop(_lua, 1); // remove value, leave key for next iteration + } + + OSG_NOTICE<<"Number of elements in Table = "<first)<<", "<second)<(lua_toboolean(_lua, -1)!=0)); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_STRING): + { + if (lua_isstring(_lua, -1)) + { + _pi.setProperty(object, propertyName, std::string(lua_tostring(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_ENUM): + case(osgDB::BaseSerializer::RW_INT): + { + if (lua_isnumber(_lua, -1)) + { + _pi.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_UINT): + { + if (lua_isnumber(_lua, -1)) + { + _pi.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_FLOAT): + { + if (lua_isnumber(_lua, -1)) + { + _pi.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_DOUBLE): + { + if (lua_isnumber(_lua, -1)) + { + _pi.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC2F): + { + if (lua_istable(_lua, -1)) + { + lua_getfield(_lua, -1, "x"); + lua_getfield(_lua, -2, "y"); + + if (lua_isnumber(_lua, -2) && + lua_isnumber(_lua, -1)) + { + _pi.setProperty(object, propertyName, osg::Vec2f(lua_tonumber(_lua, -2), lua_tonumber(_lua, -1))); + } + + lua_pop(_lua, 2); + + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC3F): + { + if (lua_istable(_lua, -1)) + { + lua_getfield(_lua, -1, "x"); + lua_getfield(_lua, -2, "y"); + lua_getfield(_lua, -3, "z"); + + if (lua_isnumber(_lua, -3) && + lua_isnumber(_lua, -2) && + lua_isnumber(_lua, -1)) + { + _pi.setProperty(object, propertyName, osg::Vec3f(lua_tonumber(_lua, -3), lua_tonumber(_lua, -2), lua_tonumber(_lua, -1))); + } + + lua_pop(_lua, 3); + + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC4F): + { + if (lua_istable(_lua, -1)) + { + lua_getfield(_lua, -1, "x"); + lua_getfield(_lua, -2, "y"); + lua_getfield(_lua, -3, "z"); + lua_getfield(_lua, -4, "w"); + + if (lua_isnumber(_lua, -4) && + lua_isnumber(_lua, -3) && + lua_isnumber(_lua, -2) && + lua_isnumber(_lua, -1)) + { + _pi.setProperty(object, propertyName, osg::Vec4f(lua_tonumber(_lua, -4), lua_tonumber(_lua, -3), lua_tonumber(_lua, -2), lua_tonumber(_lua, -1))); + } + + lua_pop(_lua, 4); + + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_MATRIX): + case(osgDB::BaseSerializer::RW_MATRIXD): + { + break; + } + default: + break; + } + OSG_NOTICE<<"LuaScriptEngine::setPropertyFromStack("<className()<<")"<(object); if (vo) { @@ -308,7 +689,16 @@ bool LuaScriptEngine::pushParameter(osg::Object* object) } else { - lua_pushstring(_lua, object->className()); + osgDB::PropertyInterface::PropertyMap properties; + lua_newtable(_lua); + lua_pushstring(_lua, "object_ptr"); lua_pushlightuserdata(_lua, object); lua_settable(_lua, -3); +#if 1 + lua_pushstring(_lua, "libraryName"); lua_pushstring(_lua, object->libraryName()); lua_settable(_lua, -3); + lua_pushstring(_lua, "className"); lua_pushstring(_lua, object->className()); lua_settable(_lua, -3); +#endif + luaL_getmetatable(_lua, "LuaScriptEngine.Object"); + lua_setmetatable(_lua, -2); + } return false; @@ -316,8 +706,6 @@ bool LuaScriptEngine::pushParameter(osg::Object* object) bool LuaScriptEngine::popParameter(osg::Object* object) { - OSG_NOTICE<<"popParameter("<className()<<")"<(object); if (vo) { @@ -327,8 +715,6 @@ bool LuaScriptEngine::popParameter(osg::Object* object) } else { - if (lua_isstring(_lua, -1)) { OSG_NOTICE<<"popParameter() string = "<