mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-19 22:27:36 -04:00
Work on lua bindings
This commit is contained in:
parent
79234e6bae
commit
d15446da29
|
@ -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
19
skelatool64/lua/scene.lua
Normal 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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -6,4 +6,6 @@
|
|||
|
||||
void fromLua(lua_State* L, DisplayListSettings& result, const DisplayListSettings& defaults);
|
||||
|
||||
void populateDisplayListSettings(lua_State* L, const DisplayListSettings& defaults);
|
||||
|
||||
#endif
|
|
@ -1,3 +1,4 @@
|
|||
EMIT(definition_writer)
|
||||
EMIT(vector3)
|
||||
EMIT(quaternion)
|
||||
EMIT(quaternion)
|
||||
EMIT(scene)
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in a new issue