2017-08-03 10 views
1

Ich habe C++ Funktion (die in meinem Spiel-Engine eine physikalische Simulation läuft), die wie folgt aussieht:interace zwischen C++ und Lua-Funktion mit 3D-Vektor-Argumente

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

Ich nenne mag diese Funktion von einem Lua Script gefällt das:

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

ich versuche, herauszufinden, wie lua-Schnittstelle für diese Funktion zu machen.

Ich möchte einige allgemeine Hilfsfunktionen zum Übergeben von 2D-, 3D- und 4D-Vektoren und Matrizen ausführen, da ich sie stark verwenden werde.

Hier Skizze, was ich zur Zeit zu tun versuchen (Aber ich weiß, dass es nicht richtig ist):

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; 
} 

ich mehrere kurze Tutorials lesen 123 aber es scheint schrecklich kompliziert, verwirrend und fehleranfällig ... Ich bin völlig in Stack-Indizes verloren (was ist meine aktuelle Position im Stack ?, was ist der richtige relative Index? usw.). Ich bin widerwillig zu glauben, dass die berühmteste Spiel-Skriptsprache so viel Code-Boiler-Plate-Code und so viel Schmerz benötigt, um jede kleine Funktion zu verbinden.


EDIT: Mit Hilfe von Vlad konnte ich es für 3D-Vektor und Matrix tun

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; 
} 

Werke für diese lua Funktion:

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

Ein lib Spitze ist Sol 2, einzelne Header-Lösung und das tut, was Sie in einfacher Art und Weise wollen. –

+0

Ich habe es schon gesehen (zusammen mit zehn anderen lua bindenden Bibliotheken). Aber die Verwendung einiger Bibliotheken fügt immer einige Probleme hinzu (Abhängigkeits-Hölle, Anforderung von C++ 14, längere Kompilierungszeit aufgrund von Vorlagen, kompliziertere Verteilung ...). Also würde ich lieber ohne es leben. –

Antwort

1

Ihre void lua_getVec3(lua_State *L, Vec3d& vec) fehlt Vitalinfo - Speicherort der Argumenttabelle auf einem Lua-Stack. Rewrite es so etwas wie:

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); 
} 

Und nennen Sie es mögen:

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

großartig, es funktioniert. Es sollte auch "Return 3" sein, oder? Gibt es etwas für die Sicherheit usw. fehlt? –

+0

hmm, tut mir leid, ich habe nicht viel gelernt ... Ich sehe nicht, wie man es zu Matrix '{{1,0, -0,1,0,1}, {- 0,2,2,0,0.2}, {- 0.3,0.3,3.0 }} ' –

+0

' return 3' wird benötigt, wenn Sie 3 Werte von Ihrer Funktion zurückgeben. Bisher ist es nur eine einzige Zahl, also 'return 1'. Matrix ist nur eine Tabelle von Tabellen. 'lua_rawget()' individuelle Vektoren aus dieser äußeren Tabelle, holen Sie die Tabellenposition des Vektors mit 'lua_gettop()' und rufen Sie 'lua_getVec3()' wie vorher auf. – Vlad

Verwandte Themen