2017-08-03 40 views
1

我有C++函數(運行我的遊戲引擎內的一些物理仿真),它看起來是這樣的:interace

void doSomePhysics(int nIters, Vec3d pos, Vec3d vel){ /*... don't care ...*/ } 

我想從一個Lua腳本中調用這個函數我喜歡這個:

doSomePhysics(100, {1.0,-2.0,3.0}, {-8.0,7.0,-6.0}) 

我想弄清楚如何使lua接口這個功能。

我想做幾個通用的輔助函數來傳遞2D,3D和4D矢量和矩陣,因爲我會大量使用它們。

這裏是素描什麼,我目前正在做的(但我知道這是不正確的):

void lua_getVec3(lua_State *L, Vec3d& vec){ 
    // universal helper function to get Vec3 function argument from Lua to C++ function 
    luaL_checktype(L, 1, LUA_TTABLE); 
    lua_settop(L, 1); 
    int a_size = lua_rawlen(L, 1); 
    lua_rawgeti(L, 1, 1); vec.x = lua_tonumber(L, -1); 
    lua_rawgeti(L, 2, 2); vec.y = lua_tonumber(L, -2); 
    lua_rawgeti(L, 3, 3); vec.z = lua_tonumber(L, -3); 
    lua_pop(L, 3); 
} 

int l_doSomePhysics(lua_State* L){ 
    // lua interface for doSomePhysics 
    Vec3d pos,vel; 
    int n = lua_tointeger(L, 1); 
    lua_getVec3(L, pos); 
    lua_getVec3(L, vel); 
    doSomePhysics(n,pos,vel); 
    lua_pushnumber(state, 123); 
    return 1; 
} 

我看了幾個簡短教程123但似乎可怕的複雜,混亂並容易出錯...我完全失去了堆棧索引(我在堆棧中的當前位置是什麼?),什麼是正確的相對索引?等等)。我不願意相信最着名的遊戲腳本語言需要這麼多的鍋爐代碼,並且爲了連接每一個小功能而痛苦不堪。


編輯:隨着弗拉德的幫助,我是能夠做到這一點的三維向量和矩陣

void lua_getVec3(lua_State *L, int idx, Vec3d& vec){ 
    // universal helper function to get Vec3 function argument from Lua to C++ function 
    luaL_checktype(L, idx, LUA_TTABLE); 
    lua_rawgeti(L, idx, 1); vec.x = lua_tonumber(L, -1); lua_pop(L, 1); 
    lua_rawgeti(L, idx, 2); vec.y = lua_tonumber(L, -1); lua_pop(L, 1); 
    lua_rawgeti(L, idx, 3); vec.z = lua_tonumber(L, -1); lua_pop(L, 1); 
} 

void lua_getMat3(lua_State *L, int idx, Mat3d& mat){ 
    // universal helper function to get Mat3 function argument from Lua to C++ function 
    luaL_checktype(L, idx, LUA_TTABLE); 
    lua_pushinteger(L, 1); lua_gettable(L, idx); lua_getVec3(L, -1, mat.a); lua_pop(L, 1); 
    lua_pushinteger(L, 2); lua_gettable(L, idx); lua_getVec3(L, -1, mat.b); lua_pop(L, 1); 
    lua_pushinteger(L, 3); lua_gettable(L, idx); lua_getVec3(L, -1, mat.c); lua_pop(L, 1); 
} 

extern "C" 
int l_doSomePhysics2(lua_State* L){ 
    // lua interface for doSomePhysics 
    Vec3d pos; 
    Mat3d mat; 
    int n = lua_tointeger(L, 1); 
    lua_getVec3(L, 2, pos); 
    lua_getMat3(L, 3, mat); 
    doSomePhysics2(n,pos,mat); 
    //lua_pushnumber(L, 123); 
    return 3; 
} 

作品爲這個盧阿功能:

mat = {{1.1,-0.1,0.1},{-0.2,2.2,0.2},{-0.3,0.3,3.3}} 
doSomePhysics2(100, {-7.7,8.8,9.9}, mat) 
+0

一個LIB提示是溶膠2,單頭解決方案,並做了你的更簡單的方法想要什麼。 –

+0

我已經在看它(和其他10個lua綁定庫一起)。但是使用某些庫總是會添加一些問題(依賴地獄,C++ 14的需求,由於模板導致編譯時間更長,分佈更復雜......)。所以我寧願沒有它而活着。 –

回答

1

void lua_getVec3(lua_State *L, Vec3d& vec)是失蹤重要信息 - 一個Lua棧上參數表的位置。它改寫爲這樣的:

void lua_getVec3(lua_State *L, int idx, Vec3d& vec){ 
    // universal helper function to get Vec3 function argument from Lua to C++ function 
    luaL_checktype(L, idx, LUA_TTABLE); 
    lua_rawgeti(L, idx, 1); vec.x = lua_tonumber(L, -1); 
    lua_rawgeti(L, idx, 2); vec.y = lua_tonumber(L, -1); 
    lua_rawgeti(L, idx, 3); vec.z = lua_tonumber(L, -1); 
    lua_pop(L, 3); 
} 

,並調用它像:

int l_doSomePhysics(lua_State* L){ 
    // lua interface for doSomePhysics 
    Vec3d pos,vel; 
    int n = lua_tointeger(L, 1); 
    lua_getVec3(L, 2, pos); 
    lua_getVec3(L, 3, vel); 
    doSomePhysics(n,pos,vel); 
    lua_pushnumber(state, 123); 
    return 1; 
} 
+0

偉大的工作。它也應該是'return 3;'對嗎?有沒有安全漏洞? –

+0

嗯,對不起,我沒有學到太多...我不知道如何推廣到矩陣'{{1.0,-0.1,0.1},{ - 0.2,2,0,0.2},{ - 0.3,0.3,3.0 }}' –

+0

'return 3'如果你從你的函數中返回3個值,將是必要的。到目前爲止,它只是一個數字,所以'返回1'。矩陣只是一張表格。 'lua_rawget()'從該外部表中獲取單個向量,使用'lua_gettop()'獲取檢索到的向量表的位置,並像以前一樣調用'lua_getVec3()'。 – Vlad

相關問題