From 8bc85764ff80bc390a5ac8ca71ab1ae4642baf6d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Sep 2013 18:43:35 +0000 Subject: [PATCH] Unified Vec/Plane/Quat handling code. --- src/osgPlugins/lua/LuaScriptEngine.cpp | 577 ++++++++++++++----------- src/osgPlugins/lua/LuaScriptEngine.h | 33 +- 2 files changed, 360 insertions(+), 250 deletions(-) diff --git a/src/osgPlugins/lua/LuaScriptEngine.cpp b/src/osgPlugins/lua/LuaScriptEngine.cpp index 24a4e9c4b..dee5fd7dc 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.cpp +++ b/src/osgPlugins/lua/LuaScriptEngine.cpp @@ -194,19 +194,10 @@ class PushStackValueVisitor : public osg::ValueObject::GetValueVisitor { public: + LuaScriptEngine* _lsg; lua_State* _lua; - PushStackValueVisitor(lua_State* lua) : _lua(lua) {} - - inline void push(const char* str, double value) - { - lua_pushstring(_lua, str); lua_pushnumber(_lua, value); lua_settable(_lua, -3); - } - - inline void pushElem(unsigned int i, double value) - { - lua_pushnumber(_lua, i); lua_pushinteger(_lua, value); lua_settable(_lua, -3); - } + PushStackValueVisitor(LuaScriptEngine* lsg) : _lsg(lsg) { _lua = lsg->getLuaState(); } virtual void apply(bool value) { lua_pushboolean(_lua, value ? 0 : 1); } virtual void apply(char value) { lua_pushnumber(_lua, value); } @@ -218,115 +209,29 @@ public: 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) { lua_newtable(_lua); push("x", value.x()); push("y", value.y()); } - virtual void apply(const osg::Vec3f& value) { lua_newtable(_lua); push("x", value.x()); push("y", value.y()); push("z", value.z()); } - virtual void apply(const osg::Vec4f& value) { lua_newtable(_lua); push("x", value.x()); push("y", value.y()); push("z", value.z()); push("w", value.w()); } - virtual void apply(const osg::Vec2d& value) { lua_newtable(_lua); push("x", value.x()); push("y", value.y()); } - virtual void apply(const osg::Vec3d& value) { lua_newtable(_lua); push("x", value.x()); push("y", value.y()); push("z", value.z()); } - virtual void apply(const osg::Vec4d& value) { lua_newtable(_lua); push("x", value.x()); push("y", value.y()); push("z", value.z()); push("w", value.w()); } - virtual void apply(const osg::Quat& value) { lua_newtable(_lua); push("x", value.x()); push("y", value.y()); push("z", value.z()); push("w", value.w()); } - virtual void apply(const osg::Plane& value) { lua_newtable(_lua); pushElem(0, value[0]); pushElem(1, value[1]); pushElem(2, value[2]); pushElem(3, value[3]); } - virtual void apply(const osg::Matrixf& value) { lua_newtable(_lua); for(unsigned int r=0; r<4; ++r) { for(unsigned int c=0; c<4; ++c) { pushElem(r*4+c, value(r,c)); } } } - virtual void apply(const osg::Matrixd& value) { lua_newtable(_lua); for(unsigned int r=0; r<4; ++r) { for(unsigned int c=0; c<4; ++c) { pushElem(r*4+c, value(r,c)); } } } + virtual void apply(const osg::Vec2f& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Vec3f& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Vec4f& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Vec2d& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Vec3d& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Vec4d& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Quat& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Plane& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Matrixf& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Matrixd& value) { _lsg->pushValue(value); } }; class GetStackValueVisitor : public osg::ValueObject::SetValueVisitor { public: + LuaScriptEngine* _lsg; lua_State* _lua; int _index; int _numberToPop; - GetStackValueVisitor(lua_State* lua, int index) : _lua(lua), _index(index), _numberToPop(0) {} + GetStackValueVisitor(LuaScriptEngine* lsg, int index) : _lsg(lsg), _lua(0), _index(index), _numberToPop(0) { _lua = lsg->getLuaState(); } - void print(int index) - { - OSG_NOTICE<<"lua_type("< - void get2(T& value) - { - if (lua_istable(_lua, _index)) - { - lua_getfield(_lua, _index, "x"); - lua_getfield(_lua, _index-1, "y"); - - if (lua_isnumber(_lua, -2)) value.x() = lua_tonumber(_lua, -2); - if (lua_isnumber(_lua, -1)) value.y() = lua_tonumber(_lua, -1); - - _numberToPop = 3; - } - } - - template - void get3(T& value) - { - if (lua_istable(_lua, _index)) - { - lua_getfield(_lua, _index, "x"); - lua_getfield(_lua, _index-1, "y"); - lua_getfield(_lua, _index-2, "z"); - - if (lua_isnumber(_lua, -3)) value.x() = lua_tonumber(_lua, -3); - if (lua_isnumber(_lua, -2)) value.y() = lua_tonumber(_lua, -2); - if (lua_isnumber(_lua, -1)) value.z() = lua_tonumber(_lua, -1); - - _numberToPop = 4; - } - } - - template - void get4(T& value) - { - if (lua_istable(_lua, _index)) - { - lua_getfield(_lua, _index, "x"); - lua_getfield(_lua, _index-1, "y"); - lua_getfield(_lua, _index-2, "z"); - lua_getfield(_lua, _index-3, "w"); - - if (lua_isnumber(_lua, -4)) value.x() = lua_tonumber(_lua, -4); - if (lua_isnumber(_lua, -3)) value.y() = lua_tonumber(_lua, -3); - if (lua_isnumber(_lua, -2)) value.z() = lua_tonumber(_lua, -2); - if (lua_isnumber(_lua, -1)) value.w() = lua_tonumber(_lua, -1); - - _numberToPop = 5; - } - } - - template - void getMatrix(T& value) - { - if (lua_istable(_lua, _index)) - { - for(unsigned int r=0; r<4; ++r) - { - for(unsigned c=0; c<4; ++c) - { - lua_rawgeti(_lua, _index, r*4+c); - if (lua_isnumber(_lua, -1)) value(r,c) = lua_tonumber(_lua, -1); - lua_pop(_lua, 1); - } - } - - _numberToPop = 1; - } - } virtual void apply(bool& value) { if (lua_isboolean(_lua, _index)) { value = (lua_toboolean(_lua, _index)!=0); _numberToPop = 1; } } virtual void apply(char& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _numberToPop = 1; } } @@ -337,33 +242,17 @@ public: virtual void apply(unsigned int& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _numberToPop = 1; } } virtual void apply(float& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _numberToPop = 1; } } virtual void apply(double& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _numberToPop = 1; } } - virtual void apply(std::string& value) { if (lua_isstring(_lua, _index)) { value = std::string(lua_tostring(_lua, _index), lua_strlen(_lua, _index)); } OSG_NOTICE<<"got string value = "<getValue(value); _numberToPop = 2;} + virtual void apply(osg::Vec3f& value) { _lsg->getValue(value); _numberToPop = 2; } + virtual void apply(osg::Vec4f& value) { _lsg->getValue(value); _numberToPop = 4; } + virtual void apply(osg::Vec2d& value) { _lsg->getValue(value); _numberToPop = 2; } + virtual void apply(osg::Vec3d& value) { _lsg->getValue(value); _numberToPop = 3; } + virtual void apply(osg::Vec4d& value) { _lsg->getValue(value); _numberToPop = 4; } + virtual void apply(osg::Quat& value) { _lsg->getValue(value); _numberToPop = 4; } + virtual void apply(osg::Plane& value) { _lsg->getValue(value); _numberToPop = 4; } + virtual void apply(osg::Matrixf& value) { _lsg->getValue(value); } + virtual void apply(osg::Matrixd& value) { _lsg->getValue(value); } }; int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& propertyName) const @@ -433,9 +322,7 @@ int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& osg::Vec2f value; if (_pi.getProperty(object, propertyName, value)) { - lua_newtable(_lua); - lua_pushstring(_lua, "x"); lua_pushnumber(_lua, value.x()); lua_settable(_lua, -3); - lua_pushstring(_lua, "y"); lua_pushnumber(_lua, value.y()); lua_settable(_lua, -3); + pushValue(value); return 1; } break; @@ -445,10 +332,7 @@ int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& osg::Vec3f value; if (_pi.getProperty(object, propertyName, value)) { - lua_newtable(_lua); - lua_pushstring(_lua, "x"); lua_pushnumber(_lua, value.x()); lua_settable(_lua, -3); - lua_pushstring(_lua, "y"); lua_pushnumber(_lua, value.y()); lua_settable(_lua, -3); - lua_pushstring(_lua, "z"); lua_pushnumber(_lua, value.z()); lua_settable(_lua, -3); + pushValue(value); return 1; } break; @@ -458,30 +342,63 @@ int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& osg::Vec4f value; if (_pi.getProperty(object, propertyName, value)) { - lua_newtable(_lua); - lua_pushstring(_lua, "x"); lua_pushnumber(_lua, value.x()); lua_settable(_lua, -3); - lua_pushstring(_lua, "y"); lua_pushnumber(_lua, value.y()); lua_settable(_lua, -3); - lua_pushstring(_lua, "z"); lua_pushnumber(_lua, value.z()); lua_settable(_lua, -3); - lua_pushstring(_lua, "w"); lua_pushnumber(_lua, value.w()); lua_settable(_lua, -3); + 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 (_pi.getProperty(object, propertyName, value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC2D): + { + osg::Vec2d value; + if (_pi.getProperty(object, propertyName, value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC3D): + { + osg::Vec3d value; + if (_pi.getProperty(object, propertyName, value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC4D): + { + osg::Vec4d value; + if (_pi.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 (_pi.getProperty(object, propertyName, value)) { - lua_newtable(_lua); - - for(unsigned int r=0; r<4; ++r) - { - for(unsigned int c=0; c<4; ++c) - { - lua_pushnumber(_lua, r*4+c); lua_pushinteger(_lua, value(r,c)); lua_settable(_lua, -3); - } - } + pushValue(value); return 1; } break; @@ -499,51 +416,7 @@ int LuaScriptEngine::setPropertyFromStack(osg::Object* object, const std::string osgDB::BaseSerializer::Type type; if (!_pi.getPropertyType(object, propertyName, type)) { - switch(lua_type(_lua, -1)) - { - case(LUA_TBOOLEAN): - { - _pi.setProperty(object, propertyName, static_cast(lua_toboolean(_lua, -1)!=0)); - return 0; - } - case(LUA_TNUMBER): - { - _pi.setProperty(object, propertyName, lua_tonumber(_lua, -1)); - return 0; - } - case(LUA_TSTRING): - { - _pi.setProperty(object, propertyName, std::string(lua_tostring(_lua, -1))); - return 0; - } - case(LUA_TTABLE): - { - typedef std::pair TypePair; - typedef std::vector< TypePair > Types; - Types types; - int n = lua_gettop(_lua); /* number of arguments */ - lua_pushnil(_lua); - while (lua_next(_lua, n) != 0) - { - types.push_back( TypePair( lua_type(_lua, -2), lua_type(_lua, -1) ) ); - lua_pop(_lua, 1); // remove value, leave key for next iteration - } - - OSG_NOTICE<<"Number of elements in Table = "<first)<<", "<second)<(object); if (vo) { - PushStackValueVisitor pvv(_lua); + PushStackValueVisitor pvv(this); vo->get(pvv); } else @@ -868,7 +961,7 @@ bool LuaScriptEngine::popParameter(osg::Object* object) osg::ValueObject* vo = dynamic_cast(object); if (vo) { - GetStackValueVisitor pvv(_lua, -1); + GetStackValueVisitor pvv(this, -1); vo->set(pvv); lua_pop(_lua, pvv._numberToPop); } diff --git a/src/osgPlugins/lua/LuaScriptEngine.h b/src/osgPlugins/lua/LuaScriptEngine.h index f1e5326a8..4269f534a 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.h +++ b/src/osgPlugins/lua/LuaScriptEngine.h @@ -45,37 +45,54 @@ class LuaScriptEngine : public osg::ScriptEngine int pushPropertyToStack(osg::Object* object, const std::string& propertyName) const; int setPropertyFromStack(osg::Object* object, const std::string& propertyName) const; - protected: - - void initialize(); - - virtual ~LuaScriptEngine(); - bool loadScript(osg::Script* script); - bool isType(int pos, osgDB::BaseSerializer::Type type) const; - osgDB::BaseSerializer::Type getType(int pos) const; + osgDB::BaseSerializer::Type getType() const; bool getfields(const char* f1, const char* f2, int type) const; bool getfields(const char* f1, const char* f2, const char* f3, int type) const; bool getfields(const char* f1, const char* f2, const char* f3, const char* f4, int type) const; bool getelements(int numElements, int type) const; + bool getvec2() const; + bool getvec3() const; + bool getvec4() const; + bool getmatrix() const; + bool getValue(osg::Vec2f& value) const; bool getValue(osg::Vec3f& value) const; bool getValue(osg::Vec4f& value) const; bool getValue(osg::Matrixf& value) const; + + bool getValue(osg::Vec2d& value) const; + bool getValue(osg::Vec3d& value) const; + bool getValue(osg::Vec4d& value) const; + bool getValue(osg::Quat& value) const; + bool getValue(osg::Plane& value) const; bool getValue(osg::Matrixd& value) const; void pushValue(const osg::Vec2f& value) const; void pushValue(const osg::Vec3f& value) const; void pushValue(const osg::Vec4f& value) const; void pushValue(const osg::Matrixf& value) const; + + void pushValue(const osg::Vec2d& value) const; + void pushValue(const osg::Vec3d& value) const; + void pushValue(const osg::Vec4d& value) const; + void pushValue(const osg::Quat& value) const; + void pushValue(const osg::Plane& value) const; void pushValue(const osg::Matrixd& value) const; bool pushParameter(osg::Object* object); bool popParameter(osg::Object* object); + protected: + + void initialize(); + + virtual ~LuaScriptEngine(); + + lua_State* _lua; typedef std::set< osg::ref_ptr > ScriptSet;