/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2013 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include "LuaScriptEngine.h" #include #include #include using namespace lua; class LuaCallbackObject : public osg::CallbackObject { public: LuaCallbackObject(const std::string& methodName, const LuaScriptEngine* lse, int ref):_lse(lse),_ref(ref) { setName(methodName); } virtual bool run(osg::Object* object, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const { int topBeforeCall = lua_gettop(_lse->getLuaState()); lua_rawgeti(_lse->getLuaState(), LUA_REGISTRYINDEX, _ref); int numInputs = 1; _lse->pushParameter(object); for(osg::Parameters::iterator itr = inputParameters.begin(); itr != inputParameters.end(); ++itr) { _lse->pushParameter(itr->get()); ++numInputs; } if (lua_pcall(_lse->getLuaState(), numInputs, LUA_MULTRET,0)!=0) { OSG_NOTICE<<"Lua error : "<getLuaState(), -1)<getLuaState()); int numReturns = topAfterCall-topBeforeCall; for(int i=1; i<=numReturns; ++i) { outputParameters.insert(outputParameters.begin(), _lse->popParameterObject()); } return true; } int getRef() const { return _ref; } protected: osg::ref_ptr _lse; int _ref; }; 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 && lua_type(_lua, 1)==LUA_TTABLE) { if (lua_type(_lua, 2)==LUA_TSTRING) { std::string propertyName = lua_tostring(_lua, 2); osg::Object* object = lse->getObjectFromTable(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 && lua_type(_lua, 1)==LUA_TTABLE) { if (lua_type(_lua, 2)==LUA_TSTRING) { std::string propertyName = lua_tostring(_lua, 2); osg::Object* object = lse->getObjectFromTable(1); return lse->setPropertyFromStack(object, propertyName); } } OSG_NOTICE<<"Warning: Lua setProperty() not matched"<(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n==2 && lua_type(_lua, 1)==LUA_TTABLE) { if (lua_type(_lua, 2)==LUA_TSTRING) { std::string propertyName = lua_tostring(_lua, 2); osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); return lse->pushPropertyToStack(object, propertyName); } else if (lua_type(_lua, 2)==LUA_TNUMBER) { double index = lua_tonumber(_lua, 2); const osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); if (vs) { const void* dataPtr = vs->getElement(*object, (unsigned int) index); if (dataPtr) { SerializerScratchPad valuesp(vs->getElementType(), dataPtr, vs->getElementSize()); return lse->pushDataToStack(&valuesp); } else { lua_pushnil(_lua); return 1; } } } } OSG_NOTICE<<"Warning: Lua getContainerProperty() not matched"<(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n==3 && lua_type(_lua, 1)==LUA_TTABLE) { if (lua_type(_lua, 2)==LUA_TSTRING) { std::string propertyName = lua_tostring(_lua, 2); osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); return lse->setPropertyFromStack(object, propertyName); } else if (lua_type(_lua, 2)==LUA_TNUMBER) { double index = lua_tonumber(_lua, 2); osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); if (vs) { SerializerScratchPad ssp; lse->getDataFromStack(&ssp, vs->getElementType(), 3); { vs->setElement(*object, (unsigned int) index, ssp.data); } } return 0; } } OSG_NOTICE<<"Warning: Lua setContainerProperty() not matched"<(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); if (vs) { lua_pushinteger(lse->getLuaState(), vs->size(*object)); return 1; } return 0; } static int callVectorClear(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); if (vs) { vs->clear(*object); return 0; } return 0; } static int callVectorResize(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 || lua_type(_lua, 2)!=LUA_TNUMBER) return 0; double numElements = lua_tonumber(lse->getLuaState(),2); osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); if (vs) { vs->resize(*object, static_cast(numElements)); } return 0; } static int callVectorReserve(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 || lua_type(_lua, 2)!=LUA_TNUMBER) return 0; double numElements = lua_tonumber(lse->getLuaState(),2); osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); if (vs) { vs->reserve(*object, static_cast(numElements)); } return 0; } static int callVectorAdd(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::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); if (vs) { 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"<(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n==2 && lua_type(_lua, 1)==LUA_TTABLE) { if (lua_type(_lua, 2)==LUA_TSTRING) { std::string propertyName = lua_tostring(_lua, 2); osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); return lse->pushPropertyToStack(object, propertyName); } else { const osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::MapBaseSerializer* ms = dynamic_cast(bs); if (ms) { SerializerScratchPad keysp; lse->getDataFromStack(&keysp, ms->getKeyType(),2); if (keysp.dataType==ms->getKeyType()) { const void* dataPtr = ms->getElement(*object, keysp.data); if (dataPtr) { SerializerScratchPad valuesp(ms->getElementType(), dataPtr, ms->getElementSize()); return lse->pushDataToStack(&valuesp); } else { lua_pushnil(_lua); return 1; } return 0; } } } } OSG_NOTICE<<"Warning: Lua getMapProperty() not matched"<(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n==3 && lua_type(_lua, 1)==LUA_TTABLE) { if (lua_type(_lua, 2)==LUA_TSTRING) { std::string propertyName = lua_tostring(_lua, 2); osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); return lse->setPropertyFromStack(object, propertyName); } else { osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::MapBaseSerializer* ms = dynamic_cast(bs); if (ms) { SerializerScratchPad keysp, valuesp; lse->getDataFromStack(&keysp, ms->getKeyType(),2); lse->getDataFromStack(&valuesp, ms->getElementType(),3); if (keysp.dataType==ms->getKeyType() && ms->getElementType()==valuesp.dataType) { ms->setElement(*object, keysp.data, valuesp.data); return 0; } else { OSG_NOTICE<<"Warning: Lua setMapProperty() : Failed to matched map element "<(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::MapBaseSerializer* ms = dynamic_cast(bs); if (ms) { ms->clear(*object); return 0; } return 0; } static int getMapSize(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::MapBaseSerializer* ms = dynamic_cast(bs); if (ms) { lua_pushinteger(lse->getLuaState(), ms->size(*object)); return 1; } return 0; } static int createMapIterator(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::MapBaseSerializer* ms = dynamic_cast(bs); if (ms) { lse->pushObject(ms->createIterator(*object)); return 1; } return 0; } static int createMapReverseIterator(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Object* object = lse->getObjectFromTable(1); std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = lse->getClassInterface().getSerializer(object, containerPropertyName, type); osgDB::MapBaseSerializer* ms = dynamic_cast(bs); if (ms) { lse->pushObject(ms->createReverseIterator(*object)); return 1; } return 0; } ////////////////////////////////////////////////////////////////////////////////////// // // MapIteratorObject support // static int callMapIteratorAdvance(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); if (mio) { lua_pushboolean(lse->getLuaState(), mio->advance()); return 1; } return 0; } static int callMapIteratorValid(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); if (mio) { lua_pushboolean(lse->getLuaState(), mio->valid()); return 1; } return 0; } static int getMapIteratorKey(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); if (mio) { const void* dataPtr = mio->getKey(); if (dataPtr) { SerializerScratchPad valuesp(mio->getKeyType(), dataPtr, mio->getKeySize()); return lse->pushDataToStack(&valuesp); } else { lua_pushnil(_lua); return 1; } } return 0; } static int getMapIteratorElement(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); if (mio) { const void* dataPtr = mio->getElement(); if (dataPtr) { SerializerScratchPad valuesp(mio->getElementType(), dataPtr, mio->getElementSize()); return lse->pushDataToStack(&valuesp); } else { lua_pushnil(_lua); return 1; } } OSG_NOTICE<<"getMapIteratorElement failed. "<(lua_topointer(_lua, lua_upvalueindex(1))); if (lua_gettop(_lua)<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); if (mio) { SerializerScratchPad valuesp; lse->getDataFromStack(&valuesp, mio->getElementType(), 2); if (mio->getElementType()==valuesp.dataType) { mio->setElement(valuesp.data); return 0; } else { OSG_NOTICE<<"Warning: Lua setMapIteratorElement() : Failed to matched map element type, valuesp.dataType="<(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("<(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Image* image = lse->getObjectFromTable(1); if (!image) { OSG_NOTICE<<"Warning: Image:allocate() can only be called on a Image"<=2 && lua_isnumber(_lua, 2)) s = static_cast(lua_tonumber(_lua, 2)); if (n>=3 && lua_isnumber(_lua, 3)) t = static_cast(lua_tonumber(_lua, 3)); if (n>=4 && lua_isnumber(_lua, 4)) r = static_cast(lua_tonumber(_lua, 4)); if (n>=5) { if (lua_isnumber(_lua, 5)) pixelFormat = static_cast(lua_tonumber(_lua, 5)); else if (lua_isstring(_lua, 5)) { pixelFormat = lse->lookUpGLenumValue(lua_tostring(_lua,5)); } } if (n>=6) { if (lua_isnumber(_lua, 6)) dataType = static_cast(lua_tonumber(_lua, 6)); else if (lua_isstring(_lua, 6)) { dataType = lse->lookUpGLenumValue(lua_tostring(_lua,6)); } } if (n>=7) { if (lua_isnumber(_lua, 7)) packing = static_cast(lua_tonumber(_lua, 7)); } if (s<=0 || t<=0 || r<=0 || pixelFormat==0 || dataType==0) { OSG_NOTICE<<"Warning: Cannot not image:allocator("<allocateImage(s,t,r,pixelFormat,dataType,packing); return 0; } static int callImageS(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Image* image = lse->getObjectFromTable(1); if (!image) { OSG_NOTICE<<"Warning: Image:s() can only be called on a Image"<s()); return 1; } static int callImageT(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Image* image = lse->getObjectFromTable(1); if (!image) { OSG_NOTICE<<"Warning: Image:t() can only be called on a Image"<t()); return 1; } static int callImageR(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Image* image = lse->getObjectFromTable(1); if (!image) { OSG_NOTICE<<"Warning: Image:r() can only be called on a Image"<r()); return 1; } // conversion of a lua value/table to a std::string, supports recursion when tables contain tables static std::string cpp_tostring(lua_State* _lua, int index) { if (!lua_istable(_lua, index)) { const char* str = lua_tostring(_lua, index); if (str) { return str; } else { return "value-cannot-be-converted-to-string"; } } // Push another reference to the table on top of the stack (so we know // where it is, and this function can work for negative, positive and // pseudo indices lua_pushvalue(_lua, index); // stack now contains: -1 => table lua_pushnil(_lua); // stack now contains: -1 => nil; -2 => table bool first = true; std::string str("{"); while (lua_next(_lua, -2)) { if (!first) str.append(", "); else first = false; // stack now contains: -1 => value; -2 => key; -3 => table // copy the key so that lua_tostring does not modify the original lua_pushvalue(_lua, -2); // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table // handle key if (lua_isstring(_lua, -1)) { const char *key = lua_tostring(_lua, -1); if (key) { str.append(key); str.append("="); } } // handle value if (lua_istable(_lua, -2)) { str.append(cpp_tostring(_lua,-2)); } else if (lua_isfunction(_lua, -2)) { str.append("function"); } else if (lua_isnil(_lua, -2)) { str.append("nil"); } else if (lua_isstring(_lua,-2)) { const char *value = lua_tostring(_lua, -2); str.append("\""); if (value) { str.append(value); } str.append("\""); } else { const char *value = lua_tostring(_lua, -2); if (value) { str.append(value); } } // pop value + copy of key, leaving original key lua_pop(_lua, 2); // stack now contains: -1 => key; -2 => table } str.append("}"); // stack now contains: -1 => table (when lua_next returns 0 it pops the key // but does not push anything.) // Pop table lua_pop(_lua, 1); // Stack is now the same as it was on entry to this function return str; } static int tostring(lua_State* _lua) { lua_pushstring(_lua, cpp_tostring(_lua,-1) .c_str()); return 1; } static int callImageGet(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::Image* image = lse->getObjectFromTable(1); if (!image) { OSG_NOTICE<<"Warning: Image:get() can only be called on a Image"<=2 && lua_isnumber(_lua, 2)) image_i = static_cast(lua_tonumber(_lua, 2)); if (n>=3 && lua_isnumber(_lua, 3)) image_j = static_cast(lua_tonumber(_lua, 3)); if (n>=4 && lua_isnumber(_lua, 4)) image_k = static_cast(lua_tonumber(_lua, 4)); const unsigned char* ptr = image->data(image_i,image_j,image_k); unsigned int numComponents = osg::Image::computeNumComponents(image->getPixelFormat()); // OSG_NOTICE<<"Need to implement Image::get("<getPixelFormat()) { case(GL_INTENSITY): lua_pushnumber(_lua, colour[0]); return 1; case(GL_LUMINANCE): lua_pushnumber(_lua, colour[0]); return 1; case(GL_ALPHA): lua_pushnumber(_lua, colour[0]); return 1; case(GL_LUMINANCE_ALPHA): { lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2); lua_pushstring(_lua, "luminance"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3); lua_pushstring(_lua, "alpha"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3); return 1; } case(GL_RGB): { lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2); lua_pushstring(_lua, "red"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3); lua_pushstring(_lua, "green"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3); lua_pushstring(_lua, "blue"); lua_pushnumber(_lua, colour[2]); lua_settable(_lua, -3); return 1; } case(GL_RGBA): { lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2); lua_pushstring(_lua, "red"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3); lua_pushstring(_lua, "green"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3); lua_pushstring(_lua, "blue"); lua_pushnumber(_lua, colour[2]); lua_settable(_lua, -3); lua_pushstring(_lua, "alpha"); lua_pushnumber(_lua, colour[3]); lua_settable(_lua, -3); return 1; } case(GL_BGR): { lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2); lua_pushstring(_lua, "red"); lua_pushnumber(_lua, colour[2]); lua_settable(_lua, -3); lua_pushstring(_lua, "green"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3); lua_pushstring(_lua, "blue"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3); return 1; } case(GL_BGRA): { lua_newtable(_lua); luaL_getmetatable(_lua, "LuaScriptEngine.Table"); lua_setmetatable(_lua, -2); lua_pushstring(_lua, "red"); lua_pushnumber(_lua, colour[2]); lua_settable(_lua, -3); lua_pushstring(_lua, "green"); lua_pushnumber(_lua, colour[1]); lua_settable(_lua, -3); lua_pushstring(_lua, "blue"); lua_pushnumber(_lua, colour[0]); lua_settable(_lua, -3); lua_pushstring(_lua, "alpha"); lua_pushnumber(_lua, colour[3]); lua_settable(_lua, -3); return 1; } } OSG_NOTICE<<"Warning: Image:get() unsupported PixelFormat"<=image->s() || image_j>=image->t() || image_k>=image->r()) { OSG_NOTICE<<"Warning: Image::set("<data(image_i,image_j,image_k); unsigned int numComponents = osg::Image::computeNumComponents(image->getPixelFormat()); switch(image->getDataType()) { case(GL_BYTE): for(unsigned int i=0; i(ptr)+i) = static_cast(colourToWrite[i]); } break; case(GL_UNSIGNED_BYTE): for(unsigned int i=0; i(ptr)+i) = static_cast(colourToWrite[i]); } break; case(GL_SHORT): for(unsigned int i=0; i(ptr)+i) = static_cast(colourToWrite[i]); } break; case(GL_UNSIGNED_SHORT): for(unsigned int i=0; i(ptr)+i) = static_cast(colourToWrite[i]); } break; case(GL_INT): for(unsigned int i=0; i(ptr)+i) = static_cast(colourToWrite[i]); } break; case(GL_UNSIGNED_INT): for(unsigned int i=0; i(ptr)+i) = static_cast(colourToWrite[i]); } break; case(GL_FLOAT): for(unsigned int i=0; i(ptr)+i) = static_cast(colourToWrite[i]); } break; case(GL_DOUBLE): for(unsigned int i=0; i(ptr)+i) = static_cast(colourToWrite[i]); } break; default: OSG_NOTICE<<"Warning: Unsupported DataType in Image::set()"<(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::Image* image = lse->getObjectFromTable(1); if (!image) { OSG_NOTICE<<"Warning: Image:set() can only be called on a Image"<=3 && lua_isnumber(_lua, 2)) { image_i = static_cast(lua_tonumber(_lua, 2)); positionSet = true; } if (n>=4 && lua_isnumber(_lua, 3)) { image_j = static_cast(lua_tonumber(_lua, 3)); positionSet = true; } if (n>=5 && lua_isnumber(_lua, 4)) { image_k = static_cast(lua_tonumber(_lua, 4)); positionSet = true; } osg::Vec4d colour(1.0,1.0,1.0,1.0); if (lua_isnumber(_lua, n)) { colour[0] = colour[1] = colour[2] = colour[3] = lua_tonumber(_lua, n); } else if (lua_istable(_lua, n)) { lua_getfield(_lua, n, "intensity"); if (lua_isnumber(_lua, -1)) { double i = lua_tonumber(_lua, -1); colour[0] = i; colour[1] = i; colour[2] = i; colour[3] = i; } lua_pop(_lua, 1); lua_getfield(_lua, n, "i"); if (lua_isnumber(_lua, -1)) { double i = lua_tonumber(_lua, -1); colour[0] = i; colour[1] = i; colour[2] = i; colour[3] = i; } lua_pop(_lua, 1); lua_getfield(_lua, n, "luminance"); if (lua_isnumber(_lua, -1)) { double l = lua_tonumber(_lua, -1); colour[0] = l; colour[1] = l; colour[2] = l; } lua_pop(_lua, 1); lua_getfield(_lua, n, "l"); if (lua_isnumber(_lua, -1)) { double l = lua_tonumber(_lua, -1); colour[0] = l; colour[1] = l; colour[2] = l; } lua_pop(_lua, 1); lua_getfield(_lua, n, "alpha"); if (lua_isnumber(_lua, -1)) { double a = lua_tonumber(_lua, -1); colour[3] = a; } lua_pop(_lua, 1); lua_getfield(_lua, n, "a"); if (lua_isnumber(_lua, -1)) { double a = lua_tonumber(_lua, -1); colour[3] = a; } lua_pop(_lua, 1); lua_getfield(_lua, n, "red"); if (lua_isnumber(_lua, -1)) { double r = lua_tonumber(_lua, -1); colour[0] = r; } lua_pop(_lua, 1); lua_getfield(_lua, n, "r"); if (lua_isnumber(_lua, -1)) { double r = lua_tonumber(_lua, -1); colour[0] = r; } lua_pop(_lua, 1); lua_getfield(_lua, n, "green"); if (lua_isnumber(_lua, -1)) { double g = lua_tonumber(_lua, -1); colour[1] = g; } lua_pop(_lua, 1); lua_getfield(_lua, n, "g"); if (lua_isnumber(_lua, -1)) { double g = lua_tonumber(_lua, -1); colour[1] = g; } lua_pop(_lua, 1); lua_getfield(_lua, n, "blue"); if (lua_isnumber(_lua, -1)) { double b = lua_tonumber(_lua, -1); colour[2] = b; } lua_pop(_lua, 1); lua_getfield(_lua, n, "b"); if (lua_isnumber(_lua, -1)) { double b = lua_tonumber(_lua, -1); colour[2] = b; } lua_pop(_lua, 1); } // repack the colour data to the final destination form osg::Vec4d colourToWrite = colour; switch(image->getPixelFormat()) { case(GL_INTENSITY): colourToWrite[0] = colour[0]; break; case(GL_LUMINANCE): colourToWrite[0] = colour[0]; break; case(GL_ALPHA): colourToWrite[0] = colour[3]; break; case(GL_LUMINANCE_ALPHA): { colourToWrite[0] = colour[0]; colourToWrite[1] = colour[3]; break; } case(GL_RGB): case(GL_RGBA): { // nothing to do as data is already in the correct form break; } case(GL_BGR): case(GL_BGRA): { colourToWrite[0] = colour[2]; colourToWrite[1] = colour[1]; colourToWrite[2] = colour[0]; colourToWrite[3] = colour[3]; return 1; } } if (positionSet) { setImageColour(image, image_i,image_j,image_k, colourToWrite); } else { for(int k=0; kr(); ++k) { for(int j=0; jt(); ++j) { for(int i=0; is(); ++i) { setImageColour(image, i,j,k, colourToWrite); } } } } return 0; } ////////////////////////////////////////////////////////////////////////////////////// // // Node Parent // static int callGetParent(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Node* node = lse->getObjectFromTable(1); if (!node) { OSG_NOTICE<<"Warning: Node::getParent() can only be called on a Node"<=2 && lua_isnumber(_lua, 2)) { index = static_cast(lua_tonumber(_lua, 2)); if (index>=0 && index(node->getNumParents())) { lse->pushObject(node->getParent(0)); return 1; } else { OSG_NOTICE<<"Warning: Call to node:getParent(index) has an out of range index."<(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; osg::Node* node = lse->getObjectFromTable(1); if (!node) { OSG_NOTICE<<"Warning: Node::getNumParents() can only be called on a Node"<getNumParents()); return 1; } ////////////////////////////////////////////////////////////////////////////////////// // // Method calling support // static int callClassMethod(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); std::string methodName = lua_tostring(_lua, lua_upvalueindex(2)); int n = lua_gettop(_lua); /* number of arguments */ if (n>=1 && lua_type(_lua, 1)==LUA_TTABLE) { osg::Object* object = lse->getObjectFromTable(1); const std::string compoundClassName = lse->getObjectCompoundClassName(1); // object->getCompoundClassName(); // OSG_NOTICE<<"callClassMethod() on "<className()<<" method name "<popParameterObject()); } if (lse->getClassInterface().run(object, compoundClassName, methodName, inputParameters, outputParameters)) { for(osg::Parameters::iterator itr = outputParameters.begin(); itr != outputParameters.end(); ++itr) { // OSG_NOTICE<<" pushing return "<<(*itr)->className()<pushParameter(itr->get()); } return outputParameters.size(); } } else { OSG_NOTICE<<"Warning: lua method called without passing object, use object::method() convention."<(reinterpret_cast(lua_touserdata(_lua, 1))); object->unref(); } } return 0; } static int newObject(lua_State * _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n==1) { if (lua_type(_lua, 1)==LUA_TSTRING) { std::string compoundName = lua_tostring(_lua, 1); lse->createAndPushObject(compoundName); return 1; } } return 0; } static int castObject(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_TSTRING && lua_type(_lua, 2)==LUA_TTABLE) { std::string new_compoundClassName = lua_tostring(_lua, 1); osg::Object* object = lse->getObjectFromTable(2); lse->pushAndCastObject(new_compoundClassName, object); return 1; } } return 0; } static int readObjectFile(lua_State * _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n==1 && lua_type(_lua, 1)==LUA_TSTRING) { std::string filename = lua_tostring(_lua, 1); osg::ref_ptr object = osgDB::readRefObjectFile(filename); if (object.valid()) { lse->pushObject(object.get()); return 1; } } return 0; } static int readImageFile(lua_State * _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n==1 && lua_type(_lua, 1)==LUA_TSTRING) { std::string filename = lua_tostring(_lua, 1); osg::ref_ptr image = osgDB::readRefImageFile(filename); if (image.valid()) { lse->pushObject(image.get()); return 1; } } return 0; } static int readNodeFile(lua_State * _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ if (n==1 && lua_type(_lua, 1)==LUA_TSTRING) { std::string filename = lua_tostring(_lua, 1); osg::ref_ptr node = osgDB::readRefNodeFile(filename); if (node.valid()) { lse->pushObject(node.get()); return 1; } } return 0; } static int writeFile(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 && lua_type(_lua, 2)==LUA_TSTRING) { osg::Object* object = lse->getObjectFromTable(1); std::string filename = lua_tostring(_lua, 2); if (object) { osgDB::writeObjectFile(*object, filename); return 1; } } return 0; } LuaScriptEngine::LuaScriptEngine(): osg::ScriptEngine("lua"), _lua(0), _scriptCount(0) { initialize(); } LuaScriptEngine::LuaScriptEngine(const LuaScriptEngine&, const osg::CopyOp&): osg::ScriptEngine("lua"), _lua(0), _scriptCount(0) { initialize(); } LuaScriptEngine::~LuaScriptEngine() { lua_close(_lua); } std::string LuaScriptEngine::createUniquieScriptName() { std::stringstream sstr; sstr<<"script_"<<_scriptCount; ++_scriptCount; return sstr.str(); } void LuaScriptEngine::initialize() { _lua = luaL_newstate(); luaL_openlibs(_lua); // provide global new method for creating osg::Object's. { lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, newObject, 1); lua_setglobal(_lua, "new"); } // provide global new method for casting osg::Object's. { lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, castObject, 1); lua_setglobal(_lua, "cast"); } // provide global new method for reading Objects { lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, readObjectFile, 1); lua_setglobal(_lua, "readFile"); } // provide global new method for reading Objects { lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, readObjectFile, 1); lua_setglobal(_lua, "readObjectFile"); } // provide global new method for reading Nodes { lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, readNodeFile, 1); lua_setglobal(_lua, "readNodeFile"); } // provide global new method for read Images { lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, readImageFile, 1); lua_setglobal(_lua, "readImageFile"); } // provide global new method for read Images { lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, writeFile, 1); lua_setglobal(_lua, "writeFile"); } // Set up the __newindex and __index methods for looking up implementations of Object properties { luaL_newmetatable(_lua, "LuaScriptEngine.Object"); lua_pushstring(_lua, "__index"); lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, getProperty, 1); lua_settable(_lua, -3); lua_pushstring(_lua, "__newindex"); lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, setProperty, 1); lua_settable(_lua, -3); lua_pushstring(_lua, "__tostring"); lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, tostring, 1); lua_settable(_lua, -3); lua_pop(_lua,1); } // Set up the __tostring methods to be able to convert tables into strings so they can be output for debugging purposes. { luaL_newmetatable(_lua, "LuaScriptEngine.Table"); lua_pushstring(_lua, "__tostring"); lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, tostring, 1); lua_settable(_lua, -3); lua_pop(_lua,1); } // Set up the __newindex and __index methods for looking up implementations of Object properties { luaL_newmetatable(_lua, "LuaScriptEngine.Container"); lua_pushstring(_lua, "__index"); lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, getContainerProperty, 1); lua_settable(_lua, -3); lua_pushstring(_lua, "__newindex"); lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, setContainerProperty, 1); lua_settable(_lua, -3); lua_pop(_lua,1); } // Set up the __newindex and __index methods for looking up implementations of Object properties { luaL_newmetatable(_lua, "LuaScriptEngine.Map"); lua_pushstring(_lua, "__index"); lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, getMapProperty, 1); lua_settable(_lua, -3); lua_pushstring(_lua, "__newindex"); lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, setMapProperty, 1); lua_settable(_lua, -3); lua_pop(_lua,1); } // Set up the __gc methods for looking up implementations of Object pointer to do the unref when the associated Lua object is destroyed. { luaL_newmetatable(_lua, "LuaScriptEngine.UnrefObject"); lua_pushstring(_lua, "__gc"); lua_pushlightuserdata(_lua, this); lua_pushcclosure(_lua, garabageCollectObject, 1); lua_settable(_lua, -3); lua_pop(_lua,1); } } bool LuaScriptEngine::loadScript(osg::Script* script) { if (_loadedScripts.count(script)!=0) return true; int loadResult = luaL_loadstring(_lua, script->getScript().c_str()); if (loadResult==0) { std::string scriptID = createUniquieScriptName(); lua_pushvalue(_lua, -1); lua_setglobal(_lua, scriptID.c_str()); _loadedScripts[script] = scriptID; return true; } else { OSG_NOTICE << "LuaScriptEngine::luaL_loadstring(Script*) error: " << lua_tostring(_lua, -1) << std::endl; return false; } } bool LuaScriptEngine::run(osg::Script* script, const std::string& entryPoint, osg::Parameters& inputParameters, osg::Parameters& outputParameters) { if (!script || !_lua) return false; if (_loadedScripts.count(script)==0) { if (!loadScript(script)) return false; if (!entryPoint.empty()) { if (lua_pcall(_lua, 0, 0, 0)!=0) { OSG_NOTICE<< "error initialize script "<< lua_tostring(_lua, -1)<second; lua_getglobal(_lua, scriptID.c_str()); } else { lua_getglobal(_lua, entryPoint.c_str()); /* function to be called */ } for(osg::Parameters::const_iterator itr = inputParameters.begin(); itr != inputParameters.end(); ++itr) { pushParameter(itr->get()); } if (lua_pcall(_lua, inputParameters.size(), LUA_MULTRET,0)!=0) { OSG_NOTICE<<"Lua error : "< obj = popParameterObject(); if (obj.valid()) outputParameters.push_back(obj); } return true; } class PushStackValueVisitor : public osg::ValueObject::GetValueVisitor { public: const LuaScriptEngine* _lse; lua_State* _lua; PushStackValueVisitor(const LuaScriptEngine* lse) : _lse(lse) { _lua = const_cast(lse)->getLuaState(); } virtual void apply(bool value) { lua_pushboolean(_lua, value ? 1 : 0); } virtual void apply(char value) { lua_pushnumber(_lua, value); } virtual void apply(unsigned char value) { lua_pushnumber(_lua, value); } virtual void apply(short value) { lua_pushnumber(_lua, value); } virtual void apply(unsigned short value) { lua_pushnumber(_lua, value); } virtual void apply(int value) { lua_pushnumber(_lua, value); } virtual void apply(unsigned int value) { lua_pushnumber(_lua, value); } virtual void apply(float value) { lua_pushnumber(_lua, value); } virtual void apply(double value) { lua_pushnumber(_lua, value); } virtual void apply(const std::string& value) { lua_pushlstring(_lua, &value[0], value.size()); } virtual void apply(const osg::Vec2f& value) { _lse->pushValue(value); } virtual void apply(const osg::Vec3f& value) { _lse->pushValue(value); } virtual void apply(const osg::Vec4f& value) { _lse->pushValue(value); } virtual void apply(const osg::Vec2d& value) { _lse->pushValue(value); } virtual void apply(const osg::Vec3d& value) { _lse->pushValue(value); } virtual void apply(const osg::Vec4d& value) { _lse->pushValue(value); } virtual void apply(const osg::Quat& value) { _lse->pushValue(value); } virtual void apply(const osg::Plane& value) { _lse->pushValue(value); } virtual void apply(const osg::Matrixf& value) { _lse->pushValue(value); } virtual void apply(const osg::Matrixd& value) { _lse->pushValue(value); } }; #if LUA_VERSION_NUM<=501 #define lua_rawlen lua_strlen #endif class GetStackValueVisitor : public osg::ValueObject::SetValueVisitor { public: const LuaScriptEngine* _lse; lua_State* _lua; int _index; int _numberToPop; bool _success; GetStackValueVisitor(const LuaScriptEngine* lse, int index) : _lse(lse), _lua(0), _index(index), _numberToPop(0), _success(false) { _lua = const_cast(lse )->getLuaState(); } virtual void apply(bool& value) { if (lua_isboolean(_lua, _index)) { value = (lua_toboolean(_lua, _index)!=0); _success=true; _numberToPop = 1; } } virtual void apply(char& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } } virtual void apply(unsigned char& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } } virtual void apply(short& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } } virtual void apply(unsigned short& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } } virtual void apply(int& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } } virtual void apply(unsigned int& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } } virtual void apply(float& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } } virtual void apply(double& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _success=true; _numberToPop = 1; } } virtual void apply(std::string& value) { if (lua_isstring(_lua, _index)) { value = std::string(lua_tostring(_lua, _index), lua_rawlen(_lua, _index)); _numberToPop = 1; } } virtual void apply(osg::Vec2f& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 2;} } virtual void apply(osg::Vec3f& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 2; } } virtual void apply(osg::Vec4f& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 4; } } virtual void apply(osg::Vec2d& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 2; } } virtual void apply(osg::Vec3d& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 3; } } virtual void apply(osg::Vec4d& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 4; } } virtual void apply(osg::Quat& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 4; } } virtual void apply(osg::Plane& value) { if (_lse->getValue(_index, value)) { _success=true; _numberToPop = 4; } } virtual void apply(osg::Matrixf& value) { if (_lse->getValue(_index, value)) { _success=true; } } virtual void apply(osg::Matrixd& value) { if (_lse->getValue(_index, value)) { _success=true; } } virtual void apply(osg::BoundingBoxf& value) { if (_lse->getValue(_index, value)) { _success=true; } } virtual void apply(osg::BoundingBoxd& value) { if (_lse->getValue(_index, value)) { _success=true; } } virtual void apply(osg::BoundingSpheref& value) { if (_lse->getValue(_index, value)) { _success=true; } } virtual void apply(osg::BoundingSphered& value) { if (_lse->getValue(_index, value)) { _success=true; } } }; int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& propertyName) const { osgDB::BaseSerializer::Type type; if (!_ci.getPropertyType(object, propertyName, type)) { if (_ci.hasMethod(object, propertyName)) { lua_pushlightuserdata(_lua, const_cast(this)); lua_pushstring(_lua, propertyName.c_str()); lua_pushcclosure(_lua, callClassMethod, 2); return 1; } osg::Object* uo = osg::getUserObject(object, propertyName); LuaCallbackObject* lco = dynamic_cast(uo); if (lco) { lua_rawgeti(_lua, LUA_REGISTRYINDEX, lco->getRef()); return 1; } else if (uo) { pushObject(uo); return 1; } OSG_INFO<<"LuaScriptEngine::pushPropertyToStack("<getIntLookup() : 0; if (lookup) { std::string enumString = lookup->getString(value); lua_pushstring(_lua, enumString.c_str()); } else { lua_pushinteger(_lua, value); } return 1; } break; } case(osgDB::BaseSerializer::RW_SHORT): { short value; if (_ci.getProperty(object, propertyName, value)) { lua_pushinteger(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_USHORT): { unsigned short value; if (_ci.getProperty(object, propertyName, value)) { lua_pushinteger(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_INT): { int value; if (_ci.getProperty(object, propertyName, value)) { lua_pushinteger(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_UINT): { unsigned int value; if (_ci.getProperty(object, propertyName, value)) { lua_pushinteger(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_FLOAT): { float value; if (_ci.getProperty(object, propertyName, value)) { lua_pushnumber(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_DOUBLE): { double value; if (_ci.getProperty(object, propertyName, value)) { lua_pushnumber(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC2F): { osg::Vec2f value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC3F): { osg::Vec3f value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC4F): { osg::Vec4f value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC2D): { osg::Vec2d value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC3D): { osg::Vec3d value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC4D): { osg::Vec4d value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } #ifdef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXF): { osg::Matrixf value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } #ifndef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXD): { osg::Matrixd value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXF): { osg::BoundingBoxf value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXD): { osg::BoundingBoxd value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF): { osg::BoundingSpheref value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED): { osg::BoundingSphered value; if (_ci.getProperty(object, propertyName, value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_LIST): { OSG_NOTICE<<"Need to implement RW_LIST support"<getObjectWrapperManager(); { const osgDB::IntLookup& lookup = ow->getLookupMap()["GL"]; const osgDB::IntLookup::ValueToString& vts = lookup.getValueToString(); osgDB::IntLookup::ValueToString::const_iterator itr = vts.find(value); if (itr!=vts.end()) return itr->second; } { const osgDB::IntLookup& lookup = ow->getLookupMap()["PrimitiveType"]; const osgDB::IntLookup::ValueToString& vts = lookup.getValueToString(); osgDB::IntLookup::ValueToString::const_iterator itr = vts.find(value); if (itr!=vts.end()) return itr->second; } OSG_NOTICE<<"Warning: LuaScriptEngine did not find valid GL enum value for GLenum value: "<getObjectWrapperManager(); { const osgDB::IntLookup& lookup = ow->getLookupMap()["GL"]; const osgDB::IntLookup::StringToValue& stv = lookup.getStringToValue(); osgDB::IntLookup::StringToValue::const_iterator itr = stv.find(str); if (itr!=stv.end()) return itr->second; } { const osgDB::IntLookup& lookup = ow->getLookupMap()["PrimitiveType"]; const osgDB::IntLookup::StringToValue& stv = lookup.getStringToValue(); osgDB::IntLookup::StringToValue::const_iterator itr = stv.find(str); if (itr!=stv.end()) return itr->second; } OSG_NOTICE<<"Warning: LuaScriptEngine did not find valid GL enum value for string value: "<dataType) { case(osgDB::BaseSerializer::RW_BOOL): { bool value; if (ssp->get(value)) { lua_pushboolean(_lua, value ? 1 : 0); return 1; } break; } case(osgDB::BaseSerializer::RW_STRING): { std::string value; if (ssp->get(value)) { lua_pushstring(_lua, value.c_str()); return 1; } break; } case(osgDB::BaseSerializer::RW_GLENUM): { GLenum value; if (ssp->get(value)) { std::string enumString = lookUpGLenumString(value); lua_pushstring(_lua, enumString.c_str()); return 1; } break; } case(osgDB::BaseSerializer::RW_ENUM): { int value; if (ssp->get(value)) { lua_pushinteger(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_INT): { int value; if (ssp->get(value)) { lua_pushinteger(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_UINT): { unsigned int value; if (ssp->get(value)) { lua_pushinteger(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_SHORT): { short value; if (ssp->get(value)) { lua_pushinteger(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_USHORT): { unsigned short value; if (ssp->get(value)) { lua_pushinteger(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_FLOAT): { float value; if (ssp->get(value)) { lua_pushnumber(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_DOUBLE): { double value; if (ssp->get(value)) { lua_pushnumber(_lua, value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC2F): { osg::Vec2f value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC3F): { osg::Vec3f value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC4F): { osg::Vec4f value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC2D): { osg::Vec2d value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC3D): { osg::Vec3d value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_VEC4D): { osg::Vec4d value; if (ssp->get(value)) { pushValue(value); return 1; } break; } #ifdef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXF): { osg::Matrixf value; if (ssp->get(value)) { pushValue(value); return 1; } break; } #ifndef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXD): { osg::Matrixd value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXF): { osg::BoundingBoxf value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXD): { osg::BoundingBoxd value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF): { osg::BoundingSpheref value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED): { osg::BoundingSphered value; if (ssp->get(value)) { pushValue(value); return 1; } break; } case(osgDB::BaseSerializer::RW_IMAGE): case(osgDB::BaseSerializer::RW_OBJECT): { osg::Object* value = 0; if (ssp->get(value)) { pushObject(value); return 1; } break; } case(osgDB::BaseSerializer::RW_LIST): { break; } case(osgDB::BaseSerializer::RW_VECTOR): { break; } default: break; } OSG_NOTICE<<"LuaScriptEngine::pushDataToStack() property of type = "<<_ci.getTypeName(ssp->dataType)<<" error, not supported."<set(static_cast(lua_toboolean(_lua, pos)!=0)); return 0; } else if (lua_isnumber(_lua, pos)) { ssp->set(static_cast(lua_tonumber(_lua, pos)!=0)); return 0; } break; } case(osgDB::BaseSerializer::RW_STRING): { if (lua_isstring(_lua, pos)) { ssp->set(std::string(lua_tostring(_lua, pos))); return 0; } break; } case(osgDB::BaseSerializer::RW_GLENUM): { if (lua_isnumber(_lua, pos)) { ssp->set(static_cast(lua_tonumber(_lua, pos))); return 0; } else if (lua_isstring(_lua, pos)) { const char* enumString = lua_tostring(_lua, pos); GLenum value = lookUpGLenumValue(enumString); //getValue("GL",enumString); ssp->set(value); return 0; } OSG_NOTICE<<"LuaScriptEngine::getDataFromStack() osgDB::BaseSerializer::RW_GLENUM Failed"<set(static_cast(lua_tonumber(_lua, pos))); return 0; } else if (lua_isstring(_lua, pos)) { OSG_NOTICE<<"LuaScriptEngine::getDataFromStack() osgDB::BaseSerializer::RW_ENUM Failed to convert string"<set(static_cast(lua_tonumber(_lua, pos))); return 0; } break; } case(osgDB::BaseSerializer::RW_USHORT): { if (lua_isnumber(_lua, pos)) { ssp->set(static_cast(lua_tonumber(_lua, pos))); return 0; } break; } case(osgDB::BaseSerializer::RW_INT): { if (lua_isnumber(_lua, pos)) { ssp->set(static_cast(lua_tonumber(_lua, pos))); return 0; } break; } case(osgDB::BaseSerializer::RW_UINT): { if (lua_isnumber(_lua, pos)) { ssp->set(static_cast(lua_tonumber(_lua, pos))); return 0; } break; } case(osgDB::BaseSerializer::RW_FLOAT): { if (lua_isnumber(_lua, pos)) { ssp->set(static_cast(lua_tonumber(_lua, pos))); return 0; } break; } case(osgDB::BaseSerializer::RW_DOUBLE): { if (lua_isnumber(_lua, pos)) { ssp->set(static_cast(lua_tonumber(_lua, pos))); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC2F): { osg::Vec2f value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC3F): { osg::Vec3f value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC4F): { osg::Vec4f value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC2D): { osg::Vec2d value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC3D): { osg::Vec3d value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC4D): { osg::Vec4d value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_QUAT): { osg::Quat value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_PLANE): { osg::Plane value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } #ifdef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXF): { osg::Matrixd value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } #ifndef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXD): { osg::Matrixd value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXF): { osg::BoundingBoxf value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXD): { osg::BoundingBoxd value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF): { osg::BoundingSpheref value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED): { osg::BoundingSphered value; if (getValue(pos, value)) { ssp->set(value); return 0; } break; } case(osgDB::BaseSerializer::RW_LIST): { OSG_NOTICE<<"Need to implement RW_LIST support"<(reinterpret_cast(lua_touserdata(_lua,-1))); lua_pop(_lua, 1); if (value) { ssp->set(value); return 0; } else { OSG_NOTICE<<"Error: lua type '"<set(value); return 0; } else { OSG_NOTICE<<"Error: lua type '"< lco = new LuaCallbackObject(propertyName, this, ref); osg::UserDataContainer* udc = object->getOrCreateUserDataContainer(); unsigned int objectIndex = udc->getUserObjectIndex(propertyName); if (objectIndex < udc->getNumUserObjects()) { udc->setUserObject(objectIndex, lco.get()); } else { udc->addUserObject(lco.get()); } return 0; } type = LuaScriptEngine::getType(-1); } return setPropertyFromStack(object, propertyName, type); } int LuaScriptEngine::setPropertyFromStack(osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type type) const { switch(type) { case(osgDB::BaseSerializer::RW_BOOL): { if (lua_isboolean(_lua, -1)) { _ci.setProperty(object, propertyName, static_cast(lua_toboolean(_lua, -1)!=0)); return 0; } else if (lua_isnumber(_lua, -1)) { _ci.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1)!=0)); return 0; } break; } case(osgDB::BaseSerializer::RW_STRING): { if (lua_isstring(_lua, -1)) { _ci.setProperty(object, propertyName, std::string(lua_tostring(_lua, -1))); return 0; } break; } case(osgDB::BaseSerializer::RW_GLENUM): { if (lua_isnumber(_lua, -1)) { _ci.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); return 0; } else if (lua_isstring(_lua, -1)) { const char* enumString = lua_tostring(_lua, -1); GLenum value = lookUpGLenumValue(enumString); //getValue("GL",enumString); _ci.setProperty(object, propertyName, value); return 0; } OSG_NOTICE<<"LuaScriptEngine::setPropertyFromStack("<(lua_tonumber(_lua, -1))); return 0; } else if (lua_isstring(_lua, -1)) { const char* enumString = lua_tostring(_lua, -1); osgDB::BaseSerializer* serializer = _ci.getSerializer(object, propertyName, type); osgDB::IntLookup* lookup = serializer ? serializer->getIntLookup() : 0; if (lookup) { int value = lookup->getValue(enumString); _ci.setProperty(object, propertyName, value); } return 0; } break; } case(osgDB::BaseSerializer::RW_SHORT): { if (lua_isnumber(_lua, -1)) { _ci.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); return 0; } break; } case(osgDB::BaseSerializer::RW_USHORT): { if (lua_isnumber(_lua, -1)) { _ci.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); return 0; } break; } case(osgDB::BaseSerializer::RW_INT): { if (lua_isnumber(_lua, -1)) { _ci.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); return 0; } break; } case(osgDB::BaseSerializer::RW_UINT): { if (lua_isnumber(_lua, -1)) { _ci.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); return 0; } break; } case(osgDB::BaseSerializer::RW_FLOAT): { if (lua_isnumber(_lua, -1)) { _ci.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); return 0; } break; } case(osgDB::BaseSerializer::RW_DOUBLE): { if (lua_isnumber(_lua, -1)) { _ci.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC2F): { osg::Vec2f value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC3F): { osg::Vec3f value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC4F): { osg::Vec4f value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC2D): { osg::Vec2d value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC3D): { osg::Vec3d value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_VEC4D): { osg::Vec4d value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_QUAT): { osg::Quat value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_PLANE): { osg::Plane value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } #ifdef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXF): { osg::Matrixd value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } #ifndef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXD): { osg::Matrixd value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXF): { osg::BoundingBoxf value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXD): { osg::BoundingBoxd value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF): { osg::BoundingSpheref value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED): { osg::BoundingSphered value; if (getValue(-1, value)) { _ci.setProperty(object, propertyName, value); return 0; } break; } case(osgDB::BaseSerializer::RW_IMAGE): case(osgDB::BaseSerializer::RW_OBJECT): { if (lua_istable(_lua, -1)) { osg::Object* value = 0; lua_pushstring(_lua, "object_ptr"); lua_rawget(_lua, -2); if (lua_type(_lua, -1)==LUA_TUSERDATA) value = *const_cast(reinterpret_cast(lua_touserdata(_lua,-1))); lua_pop(_lua, 1); if (value) { _ci.setProperty(object, propertyName, value); return 0; } else { OSG_NOTICE<<"Error: lua type '"<className()<<"::"<className()<<"::"<className()<<"::"<(object); if (vo) { PushStackValueVisitor pvv(this); vo->get(pvv); } else { pushObject( object); } return false; } bool LuaScriptEngine::popParameter(osg::Object* object) const { osg::ValueObject* vo = dynamic_cast(object); if (vo) { GetStackValueVisitor pvv(this, -1); vo->set(pvv); lua_pop(_lua, pvv._numberToPop); } else { lua_pop(_lua, 1); } return false; } osg::Object* LuaScriptEngine::popParameterObject() const { osg::ref_ptr object = 0; osgDB::BaseSerializer::Type type = getType(-1); switch(type) { case(osgDB::BaseSerializer::RW_BOOL): { if (lua_isboolean(_lua, -1)) object = new osg::BoolValueObject("", lua_toboolean(_lua, -1)!=0); break; } case(osgDB::BaseSerializer::RW_STRING): { if (lua_isstring(_lua, -1)) object = new osg::StringValueObject("", lua_tostring(_lua, -1)); break; } case(osgDB::BaseSerializer::RW_GLENUM): case(osgDB::BaseSerializer::RW_ENUM): if (lua_isstring(_lua, -1)) { object = new osg::StringValueObject("", lua_tostring(_lua, -1)); } else if (lua_isnumber(_lua, -1)) { object = new osg::IntValueObject("", static_cast(lua_tonumber(_lua, -1))); } break; case(osgDB::BaseSerializer::RW_INT): { if (lua_isnumber(_lua, -1)) object = new osg::IntValueObject("", static_cast(lua_tonumber(_lua, -1))); break; } case(osgDB::BaseSerializer::RW_UINT): { if (lua_isnumber(_lua, -1)) object = new osg::UIntValueObject("", static_cast(lua_tonumber(_lua, -1))); break; } case(osgDB::BaseSerializer::RW_FLOAT): { if (lua_isnumber(_lua, -1)) object = new osg::FloatValueObject("", static_cast(lua_tonumber(_lua, -1))); break; } case(osgDB::BaseSerializer::RW_DOUBLE): { if (lua_isnumber(_lua, -1)) object = new osg::DoubleValueObject("", static_cast(lua_tonumber(_lua, -1))); break; } case(osgDB::BaseSerializer::RW_VEC2F): { osg::Vec2f value; if (getValue(-1, value)) object = new osg::Vec2fValueObject("", value); break; } case(osgDB::BaseSerializer::RW_VEC3F): { osg::Vec3f value; if (getValue(-1, value)) object = new osg::Vec3fValueObject("", value); break; } case(osgDB::BaseSerializer::RW_VEC4F): { osg::Vec4f value; if (getValue(-1, value)) object = new osg::Vec4fValueObject("", value); break; } #ifdef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXF): { osg::Matrixf value; if (getValue(-1, value)) object = new osg::MatrixfValueObject("", value); break; } case(osgDB::BaseSerializer::RW_VEC2D): { osg::Vec2d value; if (getValue(-1, value)) object = new osg::Vec2dValueObject("", value); break; } case(osgDB::BaseSerializer::RW_VEC3D): { osg::Vec3d value; if (getValue(-1, value)) object = new osg::Vec3dValueObject("", value); break; } case(osgDB::BaseSerializer::RW_VEC4D): { osg::Vec4d value; if (getValue(-1, value)) object = new osg::Vec4dValueObject("", value); break; } case(osgDB::BaseSerializer::RW_QUAT): { osg::Quat value; if (getValue(-1, value)) object = new osg::QuatValueObject("", value); break; } case(osgDB::BaseSerializer::RW_PLANE): { osg::Plane value; if (getValue(-1, value)) object = new osg::PlaneValueObject("", value); break; } #ifndef OSG_USE_FLOAT_MATRIX case(osgDB::BaseSerializer::RW_MATRIX): #endif case(osgDB::BaseSerializer::RW_MATRIXD): { osg::Matrixd value; if (getValue(-1, value)) object = new osg::MatrixdValueObject("", value); break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXF): { osg::BoundingBoxf value; if (getValue(-1, value)) object = new osg::BoundingBoxfValueObject("", value); break; } case(osgDB::BaseSerializer::RW_BOUNDINGBOXD): { osg::BoundingBoxd value; if (getValue(-1, value)) object = new osg::BoundingBoxdValueObject("", value); break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF): { osg::BoundingSpheref value; if (getValue(-1, value)) object = new osg::BoundingSpherefValueObject("", value); break; } case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED): { osg::BoundingSphered value; if (getValue(-1, value)) object = new osg::BoundingSpheredValueObject("", value); break; } case(osgDB::BaseSerializer::RW_LIST): { OSG_NOTICE<<"Need to implement RW_LIST support"<(reinterpret_cast(lua_touserdata(_lua,-1))); } lua_pop(_lua, 1); } default: break; } lua_pop(_lua, 1); return object.release(); } void LuaScriptEngine::pushContainer(osg::Object* object, const std::string& propertyName) const { if (object) { lua_newtable(_lua); // set up objbect_ptr to handle ref/unref of the object { lua_pushstring(_lua, "object_ptr"); // create user data for pointer void* userdata = lua_newuserdata( _lua, sizeof(osg::Object*)); (*reinterpret_cast(userdata)) = object; luaL_getmetatable( _lua, "LuaScriptEngine.UnrefObject"); lua_setmetatable( _lua, -2 ); lua_settable(_lua, -3); // increment the reference count as the lua now will unreference it once it's finished with the userdata for the pointer object->ref(); } lua_pushstring(_lua, "containerPropertyName"); lua_pushstring(_lua, propertyName.c_str()); lua_settable(_lua, -3); osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* bs = _ci.getSerializer(object, propertyName, type); osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); osgDB::MapBaseSerializer* ms = dynamic_cast(bs); if (vs) { assignClosure("size", getContainerSize); assignClosure("clear", callVectorClear); assignClosure("resize", callVectorResize); assignClosure("reserve", callVectorReserve); assignClosure("add", callVectorAdd); luaL_getmetatable(_lua, "LuaScriptEngine.Container"); lua_setmetatable(_lua, -2); } else if (ms) { assignClosure("clear", callMapClear); assignClosure("size", getMapSize); assignClosure("createIterator", createMapIterator); assignClosure("createReverseIterator", createMapReverseIterator); luaL_getmetatable(_lua, "LuaScriptEngine.Map"); lua_setmetatable(_lua, -2); } else { OSG_NOTICE<<"Container type not suppported."< object = _ci.createObject(compoundName); if (!object) OSG_NOTICE<<"Failed to create object "<(userdata)) = object; luaL_getmetatable( _lua, "LuaScriptEngine.UnrefObject"); lua_setmetatable( _lua, -2 ); lua_settable(_lua, -3); // increment the reference count as the lua now will unreference it once it's finished with the userdata for the pointer object->ref(); } 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); lua_pushstring(_lua, "compoundClassName"); lua_pushstring(_lua, object->getCompoundClassName().c_str()); lua_settable(_lua, -3); // check to see if Object "is a" vector osgDB::BaseSerializer::Type type; osgDB::BaseSerializer* vs = _ci.getSerializer(object, "vector", type); if (vs) { lua_pushstring(_lua, "containerPropertyName"); lua_pushstring(_lua, "vector"); lua_settable(_lua, -3); assignClosure("size", getContainerSize); assignClosure("clear", callVectorClear); assignClosure("resize", callVectorResize); assignClosure("reserve", callVectorReserve); assignClosure("add", callVectorAdd); luaL_getmetatable(_lua, "LuaScriptEngine.Container"); lua_setmetatable(_lua, -2); } else if (dynamic_cast(object)!=0) { assignClosure("advance", callMapIteratorAdvance); assignClosure("valid", callMapIteratorValid); assignClosure("getKey", getMapIteratorKey); assignClosure("getElement", getMapIteratorElement); assignClosure("setElement", setMapIteratorElement); } else if (dynamic_cast(object)!=0) { assignClosure("allocate", callImageAllocate); assignClosure("s", callImageS); assignClosure("t", callImageT); assignClosure("r", callImageR); assignClosure("get", callImageGet); assignClosure("set", callImageSet); luaL_getmetatable(_lua, "LuaScriptEngine.Object"); lua_setmetatable(_lua, -2); } else if (dynamic_cast(object)!=0) { assignClosure("add", callStateSetSet); assignClosure("set", callStateSetSet); assignClosure("get", callStateSetGet); assignClosure("remove", callStateSetRemove); luaL_getmetatable(_lua, "LuaScriptEngine.Object"); lua_setmetatable(_lua, -2); } else if (dynamic_cast(object)!=0) { assignClosure("getParent", callGetParent); assignClosure("getNumParents", callGetNumParents); luaL_getmetatable(_lua, "LuaScriptEngine.Object"); lua_setmetatable(_lua, -2); } else { luaL_getmetatable(_lua, "LuaScriptEngine.Object"); lua_setmetatable(_lua, -2); } } else { lua_pushnil(_lua); } } void LuaScriptEngine::pushAndCastObject(const std::string& compoundClassName, osg::Object* object) const { if (object && _ci.isObjectOfType(object, compoundClassName)) { lua_newtable(_lua); // set up objbect_ptr to handle ref/unref of the object { lua_pushstring(_lua, "object_ptr"); // create user data for pointer void* userdata = lua_newuserdata( _lua, sizeof(osg::Object*)); (*reinterpret_cast(userdata)) = object; luaL_getmetatable( _lua, "LuaScriptEngine.UnrefObject"); lua_setmetatable( _lua, -2 ); lua_settable(_lua, -3); // increment the reference count as the lua now will unreference it once it's finished with the userdata for the pointer object->ref(); } std::string::size_type seperator = compoundClassName.find("::"); std::string libraryName = (seperator==std::string::npos) ? object->libraryName() : compoundClassName.substr(0, seperator); std::string className = (seperator==std::string::npos) ? object->className() : compoundClassName.substr(seperator+2,std::string::npos); lua_pushstring(_lua, "libraryName"); lua_pushstring(_lua, libraryName.c_str()); lua_settable(_lua, -3); lua_pushstring(_lua, "className"); lua_pushstring(_lua, className.c_str()); lua_settable(_lua, -3); lua_pushstring(_lua, "compoundClassName"); lua_pushstring(_lua, compoundClassName.c_str()); lua_settable(_lua, -3); luaL_getmetatable(_lua, "LuaScriptEngine.Object"); lua_setmetatable(_lua, -2); } else { lua_pushnil(_lua); } } void LuaScriptEngine::assignClosure(const char* name, lua_CFunction fn) const { lua_pushstring(_lua, name); lua_pushlightuserdata(_lua, const_cast(this)); lua_pushcclosure(_lua, fn, 1); lua_settable(_lua, -3); } void LuaScriptEngine::addPaths(const osgDB::FilePathList& paths) { lua_getglobal( _lua, "package" ); lua_getfield( _lua, -1, "path" ); std::string path = lua_tostring( _lua, -1 ); lua_pop( _lua, 1 ); OSG_NOTICE<<"LuaScriptEngine::addPaths() original package.path = "<getDatabasePathList()); }