diff --git a/src/osgPlugins/lua/LuaScriptEngine.cpp b/src/osgPlugins/lua/LuaScriptEngine.cpp index 5bd2c9207..0e999a363 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.cpp +++ b/src/osgPlugins/lua/LuaScriptEngine.cpp @@ -307,9 +307,16 @@ static int callVectorAdd(lua_State* _lua) { SerializerScratchPad ssp; lse->getDataFromStack(&ssp, vs->getElementType(), 2); + + if (ssp.dataType==vs->getElementType()) { vs->addElement(*object, ssp.data); } + else + { + OSG_NOTICE<<"Failed to match table type"<getElementType()==valuesp.dataType) { - OSG_NOTICE<<"Assigning element "<setElement(valuesp.data); return 0; } @@ -620,6 +626,521 @@ static int setMapIteratorElement(lua_State* _lua) } +////////////////////////////////////////////////////////////////////////////////////// +// +// StateSet support +// +static int convertStringToStateAttributeValue(const std::string& valueString, osg::StateAttribute::OverrideValue defaultValue, bool& setOnOff) +{ + osg::StateAttribute::OverrideValue value=defaultValue; + + if (valueString.find("ON")!=std::string::npos) { value = osg::StateAttribute::ON; setOnOff = true; } + if (valueString.find("OFF")!=std::string::npos) { value = osg::StateAttribute::OFF; setOnOff = true; } + + if (valueString.find("OVERRIDE")!=std::string::npos) value = value | osg::StateAttribute::OVERRIDE; + if (valueString.find("PROTECTED")!=std::string::npos) value = value | osg::StateAttribute::PROTECTED; + if (valueString.find("INHERIT")!=std::string::npos) value = value | osg::StateAttribute::INHERIT; + return value; +} + +static std::string convertStateAttributeValueToString(unsigned int value, bool withOnOffCheck) +{ + std::string valueString; + if (withOnOffCheck) + { + if ((value&osg::StateAttribute::ON)!=0) { if (!valueString.empty()) valueString.append(", "); valueString.append("ON"); } + else { if (!valueString.empty()) valueString.append(", "); valueString.append("OFF"); } + } + if ((value&osg::StateAttribute::OVERRIDE)!=0) { if (!valueString.empty()) valueString.append(", "); valueString.append("OVERRIDE"); } + if ((value&osg::StateAttribute::PROTECTED)!=0) { if (!valueString.empty()) valueString.append(", "); valueString.append("PROTECTED"); } + if ((value&osg::StateAttribute::INHERIT)!=0) { if (!valueString.empty()) valueString.append(", "); valueString.append("INHERIT"); } + return valueString; +} + +static int callStateSetSet(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 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + + osg::StateSet* stateset = lse->getObjectFromTable(1); + if (!stateset) + { + OSG_NOTICE<<"Warning: StateSet:add() can only be called on a StateSet"<getObjectFromTable(2); + osg::StateAttribute* sa = dynamic_cast(po); + osg::Uniform* uniform = dynamic_cast(po); + + osg::StateAttribute::OverrideValue value=osg::StateAttribute::ON; + bool setOnOff = false; + if (n>=3 && lua_type(_lua,3)==LUA_TSTRING) + { + value = convertStringToStateAttributeValue(lua_tostring(_lua, 3), value, setOnOff); + } + + if (sa) + { + if (setOnOff) + { + if (sa->isTextureAttribute()) stateset->setTextureAttributeAndModes(0, sa, value); + else stateset->setAttributeAndModes(sa, value); + } + else + { + if (sa->isTextureAttribute()) stateset->setTextureAttribute(0, sa, value); + else stateset->setAttribute(sa, value); + } + return 0; + } + else if (uniform) + { + stateset->addUniform(uniform, value); + return 0; + } + } + else if (lua_type(_lua,2)==LUA_TNUMBER) + { + double index = lua_tonumber(_lua, 2); + if (n>=3) + { + if (lua_type(_lua,3)==LUA_TTABLE) + { + osg::Object* po = lse->getObjectFromTable(3); + osg::StateAttribute* sa = dynamic_cast(po); + + osg::StateAttribute::OverrideValue value=osg::StateAttribute::ON; + bool setOnOff = false; + if (n>=4 && lua_type(_lua,4)==LUA_TSTRING) + { + value = convertStringToStateAttributeValue(lua_tostring(_lua, 4), value, setOnOff); + } + + if (sa) + { + if (setOnOff) + { + stateset->setTextureAttributeAndModes(static_cast(index), sa, value); + } + else + { + stateset->setTextureAttribute(static_cast(index), sa, value); + } + return 0; + } + } + else if (lua_type(_lua,3)==LUA_TSTRING) + { + std::string modeString = lua_tostring(_lua, 3); + GLenum mode = lse->lookUpGLenumValue(modeString); + + osg::StateAttribute::OverrideValue value=osg::StateAttribute::ON; + bool setOnOff = false; + if (n>=4 && lua_type(_lua,4)==LUA_TSTRING) + { + value = convertStringToStateAttributeValue(lua_tostring(_lua, 4), value, setOnOff); + } + stateset->setTextureMode(static_cast(index), mode, value); + return 0; + } + } + } + else if (lua_type(_lua,2)==LUA_TSTRING) + { + std::string modeString = lua_tostring(_lua, 2); + GLenum mode = lse->lookUpGLenumValue(modeString); + if (n>=3) + { + osg::StateAttribute::OverrideValue value=osg::StateAttribute::ON; + bool setOnOff = false; + if (lua_type(_lua,3)==LUA_TSTRING) + { + value = convertStringToStateAttributeValue(lua_tostring(_lua, 3), value, setOnOff); + } + + stateset->setMode(mode, value); + return 0; + } + } + + OSG_NOTICE<<"Warning: StateSet:set() inappropriate parameters, use form:"<(lua_topointer(_lua, lua_upvalueindex(1))); + int n = lua_gettop(_lua); /* number of arguments */ + if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + + osg::StateSet* stateset = lse->getObjectFromTable(1); + if (!stateset) + { + OSG_NOTICE<<"Warning: StateSet:get() can only be called on a StateSet"<(lua_tonumber(_lua, 2)); + if (lua_type(_lua,3)==LUA_TTABLE) + { + osg::Object* po = lse->getObjectFromTable(3); + osg::StateAttribute* sa = dynamic_cast(po); + if (sa && sa->isTextureAttribute()) + { + if (stateset->getTextureAttributeList().size()>index) + { + const osg::StateSet::AttributeList& al = stateset->getTextureAttributeList()[index]; + for(osg::StateSet::AttributeList::const_iterator itr = al.begin(); + itr != al.end(); + ++itr) + { + if (itr->second.first==sa) + { + lua_newtable(_lua); + lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3); + lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3); + return 1; + } + } + } + OSG_NOTICE<<"Warning: StateSet:get() Could not find attribute : "<className()<getTextureAttributeList().size()>index) + { + const osg::StateSet::AttributeList& al = stateset->getTextureAttributeList()[index]; + for(osg::StateSet::AttributeList::const_iterator itr = al.begin(); + itr != al.end(); + ++itr) + { + if (value == itr->second.first->className() || + value == itr->second.first->getName()) + { + lua_newtable(_lua); + lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3); + lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3); + return 1; + } + } + } + if (stateset->getTextureModeList().size()>index) + { + osg::StateAttribute::GLMode mode = lse->lookUpGLenumValue(value); + const osg::StateSet::ModeList& ml = stateset->getTextureModeList()[index]; + for(osg::StateSet::ModeList::const_iterator itr = ml.begin(); + itr != ml.end(); + ++itr) + { + if (mode == itr->first) + { + lua_pushstring(_lua, convertStateAttributeValueToString(itr->second, true).c_str()); + return 1; + } + } + } + + OSG_NOTICE<<"Warning: StateSet:get() Could not find attribute : "<getObjectFromTable(2); + osg::StateAttribute* sa = dynamic_cast(po); + osg::Uniform* uniform = dynamic_cast(po); + + if (sa && sa->isTextureAttribute() && stateset->getTextureAttributeList().size()>0) + { + const osg::StateSet::AttributeList& al = stateset->getTextureAttributeList()[0]; + for(osg::StateSet::AttributeList::const_iterator itr = al.begin(); + itr != al.end(); + ++itr) + { + if (itr->second.first==sa) + { + lua_newtable(_lua); + lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3); + lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3); + return 1; + } + } + OSG_NOTICE<<"Warning: StateSet:get("<className()<<") Could not find attribute"<getAttributeList(); + for(osg::StateSet::AttributeList::const_iterator itr = al.begin(); + itr != al.end(); + ++itr) + { + if (itr->second.first==sa) + { + lua_newtable(_lua); + lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3); + lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3); + return 1; + } + } + OSG_NOTICE<<"Warning: StateSet:get("<className()<<") Could not find attribute"<getUniformList(); + for(osg::StateSet::UniformList::const_iterator itr = ul.begin(); + itr != ul.end(); + ++itr) + { + if (itr->second.first==uniform) + { + lua_newtable(_lua); + lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3); + lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3); + return 1; + } + } + OSG_NOTICE<<"Warning: StateSet:get("<className()<<") Could not find uniform"<getAttributeList(); + for(osg::StateSet::AttributeList::const_iterator itr = al.begin(); + itr != al.end(); + ++itr) + { + if (value == itr->second.first->className() || + value == itr->second.first->getName()) + { + lua_newtable(_lua); + lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3); + lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3); + return 1; + } + } + + const osg::StateSet::UniformList& ul = stateset->getUniformList(); + for(osg::StateSet::UniformList::const_iterator itr = ul.begin(); + itr != ul.end(); + ++itr) + { + if (value == itr->second.first->className() || + value == itr->second.first->getName()) + { + lua_newtable(_lua); + lua_pushstring(_lua, "attribute"); lse->pushObject(itr->second.first.get()); lua_settable(_lua, -3); + lua_pushstring(_lua, "value"); lua_pushstring(_lua, convertStateAttributeValueToString(itr->second.second, false).c_str()); lua_settable(_lua, -3); + return 1; + } + } + + osg::StateAttribute::GLMode mode = lse->lookUpGLenumValue(value); + const osg::StateSet::ModeList& ml = stateset->getModeList(); + for(osg::StateSet::ModeList::const_iterator itr = ml.begin(); + itr != ml.end(); + ++itr) + { + if (mode == itr->first) + { + lua_pushstring(_lua, convertStateAttributeValueToString(itr->second, true).c_str()); + return 1; + } + } + + OSG_NOTICE<<"Warning: StateSet:get("<(lua_topointer(_lua, lua_upvalueindex(1))); + int n = lua_gettop(_lua); /* number of arguments */ + if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + + osg::StateSet* stateset = lse->getObjectFromTable(1); + if (!stateset) + { + OSG_NOTICE<<"Warning: StateSet:remove() can only be called on a StateSet"<(lua_tonumber(_lua, 2)); + if (lua_type(_lua,3)==LUA_TTABLE) + { + osg::Object* po = lse->getObjectFromTable(3); + osg::StateAttribute* sa = dynamic_cast(po); + stateset->removeTextureAttribute(static_cast(index), sa); + return 0; + } + else if (lua_type(_lua,3)==LUA_TSTRING) + { + std::string value = lua_tostring(_lua, 3); + if (stateset->getTextureAttributeList().size()>index) + { + const osg::StateSet::AttributeList& al = stateset->getTextureAttributeList()[index]; + for(osg::StateSet::AttributeList::const_iterator itr = al.begin(); + itr != al.end(); + ++itr) + { + if (value == itr->second.first->className() || + value == itr->second.first->getName()) + { + stateset->removeTextureAttribute(index, itr->second.first.get()); + return 0; + } + } + } + + if (stateset->getTextureModeList().size()>index) + { + osg::StateAttribute::GLMode mode = lse->lookUpGLenumValue(value); + const osg::StateSet::ModeList& ml = stateset->getTextureModeList()[static_cast(index)]; + for(osg::StateSet::ModeList::const_iterator itr = ml.begin(); + itr != ml.end(); + ++itr) + { + if (mode == itr->first) + { + stateset->removeTextureMode(static_cast(index), mode); + return 1; + } + } + } + + OSG_NOTICE<<"Warning: StateSet:remove("<getObjectFromTable(2); + osg::StateAttribute* sa = dynamic_cast(po); + osg::Uniform* uniform = dynamic_cast(po); + + if (sa && sa->isTextureAttribute()) + { + stateset->removeTextureAttribute(0, sa); + return 0; + } + else if (sa) + { + stateset->removeAttribute(sa); + return 0; + } + else if (uniform) + { + stateset->removeUniform(uniform); + return 0; + } + } + else if (lua_type(_lua,2)==LUA_TSTRING) + { + std::string value = lua_tostring(_lua, 2); + const osg::StateSet::AttributeList& al = stateset->getAttributeList(); + for(osg::StateSet::AttributeList::const_iterator itr = al.begin(); + itr != al.end(); + ++itr) + { + if (value == itr->second.first->className() || + value == itr->second.first->getName()) + { + stateset->removeAttribute(itr->second.first.get()); + return 0; + } + } + + const osg::StateSet::UniformList& ul = stateset->getUniformList(); + for(osg::StateSet::UniformList::const_iterator itr = ul.begin(); + itr != ul.end(); + ++itr) + { + if (value == itr->second.first->className() || + value == itr->second.first->getName()) + { + stateset->removeUniform(itr->second.first.get()); + return 0; + } + } + + osg::StateAttribute::GLMode mode = lse->lookUpGLenumValue(value); + const osg::StateSet::ModeList& ml = stateset->getModeList(); + for(osg::StateSet::ModeList::const_iterator itr = ml.begin(); + itr != ml.end(); + ++itr) + { + if (mode == itr->first) + { + stateset->removeMode(mode); + return 1; + } + } + + + OSG_NOTICE<<"Warning: StateSet:remove("<(reinterpret_cast(lua_touserdata(_lua,-1))); + if (lua_type(_lua, -1)==LUA_TUSERDATA) value = *const_cast(reinterpret_cast(lua_touserdata(_lua,-1))); lua_pop(_lua, 1); if (value) @@ -3138,6 +3659,33 @@ void LuaScriptEngine::pushObject(osg::Object* object) const assignClosure("getElement", getMapIteratorElement); assignClosure("setElement", setMapIteratorElement); } + else if (dynamic_cast(object)!=0) + { + OSG_NOTICE<<"Have osg::Image need to implement Image methods"<(object)!=0) + { + OSG_NOTICE<<"Have osg::StateSet need to implement stateset methods"<