Work on lua bindings

This commit is contained in:
James Lambert 2022-09-13 13:18:24 -06:00
parent 79234e6bae
commit d15446da29
12 changed files with 182 additions and 11 deletions

View file

@ -3,4 +3,8 @@ Quaternion = {}
function quaternion(x, y, z, w)
return setmetatable({ x = x, y = y, z = z, w = w }, Quaternion)
end
function Quaternion.__tostring(v)
return 'quaternion(' .. v.x .. ', ' .. v.y .. ', ' .. v.z .. ', ' .. v.w .. ')'
end

19
skelatool64/lua/scene.lua Normal file
View file

@ -0,0 +1,19 @@
local node_name_cache = nil
local function build_node_with_name_cache(node)
node_name_cache[node.name] = node
for _, child in pairs(node.children) do
build_node_with_name_cache(child)
end
end
function node_with_name(name)
if (not node_name_cache) then
node_name_cache = {}
build_node_with_name_cache(scene.root)
end
return node_name_cache[name]
end

View file

@ -19,4 +19,8 @@ function Vector3.__add(a, b)
end
return vector3(a.x + b.x, a.y + b.y, a.z + b.z)
end
function Vector3.__tostring(v)
return 'vector3(' .. v.x .. ', ' .. v.y .. ', ' .. v.z .. ')'
end

View file

@ -24,11 +24,25 @@ void DefinitionGenerator::TraverseScene(const aiScene* scene) {
void DefinitionGenerator::BeforeTraversal(const aiScene* scene) {}
NodeGroups::NodeGroups(const aiScene* scene) {
forEachNode(scene->mRootNode, [&](aiNode* node) -> void {
if (node->mName.data[0] == '@') {
AddNode(node);
}
});
RecurseAddNode(scene->mRootNode, false);
}
void NodeGroups::RecurseAddNode(aiNode* node, bool isSpecialNode) {
if (!node) {
return;
}
if (node->mName.data[0] == '@') {
AddNode(node);
isSpecialNode = true;
} else if (!isSpecialNode) {
AddNode(node);
}
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
RecurseAddNode(node->mChildren[i], isSpecialNode);
}
}
std::vector<NodeWithArguments>& NodeGroups::NodesForType(const std::string& typeName) {
@ -47,9 +61,14 @@ void NodeGroups::PrintUnusedTypes() {
void NodeGroups::AddNode(aiNode* node) {
NodeWithArguments result;
SplitString(node->mName.C_Str(), ' ', result.arguments);
std::string typeName = result.arguments[0];
std::string typeName;
result.node = node;
result.arguments.erase(result.arguments.begin());
if (result.arguments[0][0] == '@') {
typeName = result.arguments[0];
result.arguments.erase(result.arguments.begin());
}
mNodesByType[typeName].push_back(result);
}

View file

@ -42,6 +42,8 @@ public:
private:
void AddNode(aiNode* node);
void RecurseAddNode(aiNode* node, bool isSpecialNode);
std::map<std::string, std::vector<NodeWithArguments>> mNodesByType;
std::set<std::string> mTypesReferenced;
};

View file

@ -56,7 +56,6 @@ template <typename T> void toLua(lua_State* L, const T* array, unsigned count) {
for (unsigned i = 0; i < count; ++i) {
toLua(L, array[i]);
lua_seti(L, tableIndex, i + 1);
++i;
}
}

View file

@ -2,6 +2,7 @@
#include <string.h>
#include "./LuaMesh.h"
#include "LuaTransform.h"
Material* luaGetMaterial(lua_State* L, const DisplayListSettings& defaults) {
int materialType = lua_type(L, -1);
@ -51,4 +52,16 @@ void fromLua(lua_State* L, DisplayListSettings& result, const DisplayListSetting
lua_pop(L, 1);
}
}
void populateDisplayListSettings(lua_State* L, const DisplayListSettings& defaults) {
lua_newtable(L);
toLua(L, defaults.CreateCollisionTransform());
lua_setfield(L, -2, "model_transform");
toLua(L, defaults.CreateGlobalTransform());
lua_setfield(L, -2, "fixed_point_transform");
lua_setglobal(L, "settings");
}

View file

@ -6,4 +6,6 @@
void fromLua(lua_State* L, DisplayListSettings& result, const DisplayListSettings& defaults);
void populateDisplayListSettings(lua_State* L, const DisplayListSettings& defaults);
#endif

View file

@ -1,3 +1,4 @@
EMIT(definition_writer)
EMIT(vector3)
EMIT(quaternion)
EMIT(quaternion)
EMIT(scene)

View file

@ -6,6 +6,7 @@
#include "LuaNodeGroups.h"
#include "LuaScene.h"
#include "LuaMesh.h"
#include "LuaDisplayListSettings.h"
#include <lua.hpp>
#include <iostream>
@ -52,10 +53,10 @@ void generateFromLuaScript(
lua_State *L = luaL_newstate();
luaL_openlibs(L);
generateLuaTransform(L);
populateLuaScene(L, scene);
populateLuaNodeGroups(L, nodeGroups);
populateLuaMesh(L, scene, fileDefinition, settings);
populateLuaDefinitionWrite(L, fileDefinition);
populateDisplayListSettings(L, settings);
for (unsigned i = 0; i < sizeof(luaFiles) / sizeof(*luaFiles); ++i) {
struct LuaFile* file = &luaFiles[i];
@ -71,6 +72,8 @@ void generateFromLuaScript(
lua_settop(L, stackSize);
}
populateLuaScene(L, scene);
std::string directory = DirectoryName(filename) + "/?.lua;";
// set the directory of the script location as a search path

View file

@ -4,6 +4,24 @@
#include "LuaTransform.h"
#include <iostream>
aiMatrix4x4 nodeFullTrasformation(lua_State* L, const aiNode* node) {
aiMatrix4x4 result;
while (node) {
result = node->mTransformation * result;
node = node->mParent;
}
lua_getglobal(L, "settings");
lua_getfield(L, -1, "model_transform");
aiMatrix4x4* modelTransform = (aiMatrix4x4*)lua_touserdata(L, -1);
lua_pop(L, 2);
return (*modelTransform) * result;
}
void toLua(lua_State* L, const aiNode* node) {
if (!node) {
lua_pushnil(L);
@ -36,6 +54,10 @@ void toLua(lua_State* L, const aiNode* node) {
toLua(L, node->mTransformation);
lua_setfield(L, tableIndex, "transformation");
aiMatrix4x4 fullTransformation = nodeFullTrasformation(L, node);
toLua(L, fullTransformation);
lua_setfield(L, tableIndex, "full_transformation");
// save node into the cache before building related nodes
lua_pushlightuserdata(L, const_cast<aiNode*>(node));
lua_pushnil(L);
@ -57,8 +79,52 @@ void fromLua(lua_State* L, aiNode *& node) {
lua_pop(L, 2);
}
void toLua(lua_State* L, const aiCamera* camera) {
lua_createtable(L, 0, 2);
toLua(L, std::string(camera->mName.C_Str()));
lua_setfield(L, -2, "name");
toLua(L, camera->mPosition);
lua_setfield(L, -2, "position");
toLua(L, camera->mLookAt);
lua_setfield(L, -2, "look_at");
toLua(L, camera->mUp);
lua_setfield(L, -2, "up");
toLua(L, camera->mHorizontalFOV);
lua_setfield(L, -2, "horizontal_fov");
toLua(L, camera->mClipPlaneNear);
lua_setfield(L, -2, "near_plane");
toLua(L, camera->mClipPlaneFar);
lua_setfield(L, -2, "far_plane");
toLua(L, camera->mAspect);
lua_setfield(L, -2, "aspect_ratio");
aiVector3D right = camera->mUp ^ camera->mLookAt;
aiMatrix3x3 rotation;
rotation.a1 = right.x; rotation.b1 = camera->mUp.x; rotation.c1 = camera->mLookAt.x;
rotation.a2 = right.y; rotation.b2 = camera->mUp.y; rotation.c2 = camera->mLookAt.y;
rotation.a3 = right.z; rotation.b3 = camera->mUp.z; rotation.c3 = camera->mLookAt.z;
aiMatrix4x4 translation;
aiMatrix4x4::Translation(camera->mPosition, translation);
aiMatrix4x4 localTransform = translation * aiMatrix4x4(rotation);
toLua(L, localTransform);
lua_setfield(L, -2, "local_transform");
}
void toLua(lua_State* L, const aiScene* scene) {
lua_createtable(L, 0, 1);
lua_createtable(L, 0, 2);
int tableIndex = lua_gettop(L);
luaL_getmetatable(L, "aiScene");
lua_setmetatable(L, tableIndex);
@ -68,6 +134,9 @@ void toLua(lua_State* L, const aiScene* scene) {
toLua(L, scene->mRootNode);
lua_setfield(L, tableIndex, "root");
toLua(L, scene->mCameras, scene->mNumCameras);
lua_setfield(L, tableIndex, "cameras");
}
void populateLuaScene(lua_State* L, const aiScene* scene) {

View file

@ -79,11 +79,47 @@ int luaTransformIndex(lua_State* L) {
return 0;
}
bool luaIsTransform(lua_State* L, int idx) {
if (lua_type(L, idx) != LUA_TUSERDATA) {
return false;
}
if (!lua_getmetatable(L, idx)) {
return false;
}
luaL_getmetatable(L, "aiMatrix4x4");
bool result = lua_rawequal(L, -2, -1);
lua_pop(L, 2);
return result;
}
int luaTransformMul(lua_State* L) {
aiMatrix4x4* a = (aiMatrix4x4*)luaL_checkudata(L, 1, "aiMatrix4x4");
if (luaIsTransform(L, 2)) {
aiMatrix4x4* b = (aiMatrix4x4*)luaL_checkudata(L, 2, "aiMatrix4x4");
aiMatrix4x4 result = (*a) * (*b);
toLua(L, result);
return 1;
}
luaL_checkudata(L, 2, "aiMatrix4x4");
return 0;
}
void generateLuaTransform(lua_State* L) {
luaL_newmetatable(L, "aiMatrix4x4");
lua_pushcfunction(L, luaTransformIndex);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, luaTransformMul);
lua_setfield(L, -2, "__mul");
lua_pop(L, 1);
}