Work on lua bindings
This commit is contained in:
parent
134cd46d40
commit
a9b9f336c9
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,6 +5,8 @@
|
||||||
*.z64
|
*.z64
|
||||||
*.blend1
|
*.blend1
|
||||||
|
|
||||||
|
lua-5.4.4/
|
||||||
|
|
||||||
build/
|
build/
|
||||||
debugger
|
debugger
|
||||||
gfxvalidator
|
gfxvalidator
|
||||||
|
|
198
skelatool64/lua/definition_writer.lua
Normal file
198
skelatool64/lua/definition_writer.lua
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
|
||||||
|
local pending_definitions = {}
|
||||||
|
|
||||||
|
local RefType = {}
|
||||||
|
|
||||||
|
function reference_to(value)
|
||||||
|
return setmetatable({ value = value }, RefType)
|
||||||
|
end
|
||||||
|
|
||||||
|
function is_reference_type(value)
|
||||||
|
return getmetatable(value) == RefType
|
||||||
|
end
|
||||||
|
|
||||||
|
local RawType = {}
|
||||||
|
|
||||||
|
function raw(value)
|
||||||
|
return setmetatable({ value = value}, RawType)
|
||||||
|
end
|
||||||
|
|
||||||
|
function is_raw(value)
|
||||||
|
return getmetatable(value) == RawType
|
||||||
|
end
|
||||||
|
|
||||||
|
local MacroType = {}
|
||||||
|
|
||||||
|
function macro(name, ...)
|
||||||
|
if (type(name) ~= "string") then
|
||||||
|
error("name should be of type string got " .. type(name))
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable({ name = name, args = {...}}, MacroType)
|
||||||
|
end
|
||||||
|
|
||||||
|
function is_macro(value)
|
||||||
|
return getmetatable(value) == MacroType
|
||||||
|
end
|
||||||
|
|
||||||
|
local function validate_definition(data, visited, name_path)
|
||||||
|
if (visited[data]) then
|
||||||
|
error("Circular reference found '" .. name_path .. "'")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local data_type = type(data)
|
||||||
|
|
||||||
|
if (data_type == "nil" or data_type == "boolean" or data_type == "number" or data_type == "string") then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if (data_type == "function" or data_type == "userdata" or data_type == "thread") then
|
||||||
|
error("Cannot use '" .. data_type .. "' in a c file definition for path '" .. name_path .. "'")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if (is_reference_type(data) or is_raw(data)) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
visited[data] = true
|
||||||
|
|
||||||
|
for k, v in pairs(data) do
|
||||||
|
local key_type = type(k)
|
||||||
|
|
||||||
|
if (key_type ~= "string" and key_type ~= "number") then
|
||||||
|
error("Cannot use '" .. data_type .. "' as a key in a c file definiton for path '" .. name_path .. "'")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local name
|
||||||
|
|
||||||
|
if (key_type == "number") then
|
||||||
|
name = name_path .. "[" .. (k - 1) .. "]"
|
||||||
|
else
|
||||||
|
name = name_path .. "." .. k
|
||||||
|
end
|
||||||
|
|
||||||
|
if (not validate_definition(v, visited, name)) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
visited[data] = nil
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function add_definition(nameHint, dataType, location, data)
|
||||||
|
if (type(nameHint) ~= "string") then
|
||||||
|
error("nameHint should be a string")
|
||||||
|
end
|
||||||
|
|
||||||
|
if (type(dataType) ~= "string") then
|
||||||
|
error("dataType should be a string")
|
||||||
|
end
|
||||||
|
|
||||||
|
if (type(location) ~= "string") then
|
||||||
|
error("location should be a string")
|
||||||
|
end
|
||||||
|
|
||||||
|
if (not validate_definition(data, {}, nameHint)) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(pending_definitions, {
|
||||||
|
nameHint = nameHint,
|
||||||
|
dataType = dataType,
|
||||||
|
location = location,
|
||||||
|
data = data
|
||||||
|
})
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function populate_name_mapping(path, object, result)
|
||||||
|
if (type(object) ~= "table") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if (is_reference_type(object) or is_macro(object)) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
result[object] = path
|
||||||
|
|
||||||
|
for k, v in pairs(object) do
|
||||||
|
if type(k) == "number" then
|
||||||
|
populate_name_mapping(path .. "[" .. (k - 1) .. "]", v, result)
|
||||||
|
else
|
||||||
|
populate_name_mapping(path .. "." .. k, v, result)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function replace_references(object, name_mapping, name_path)
|
||||||
|
if type(object) ~= "table" then
|
||||||
|
return object
|
||||||
|
end
|
||||||
|
|
||||||
|
if (is_reference_type(object)) then
|
||||||
|
local referenceName = name_mapping[object.value]
|
||||||
|
|
||||||
|
if (referenceName == nil) then
|
||||||
|
error("A reference '" .. name_path .. "' was used on an object not exported in a definition")
|
||||||
|
end
|
||||||
|
|
||||||
|
return raw("&" .. referenceName)
|
||||||
|
end
|
||||||
|
|
||||||
|
local changes = {}
|
||||||
|
local hasChanges = false
|
||||||
|
|
||||||
|
for k, v in pairs(object) do
|
||||||
|
local name
|
||||||
|
|
||||||
|
if (type(k) == "number") then
|
||||||
|
name = name_path .. "[" .. (k - 1) .. "]"
|
||||||
|
else
|
||||||
|
name = name_path .. "." .. k
|
||||||
|
end
|
||||||
|
|
||||||
|
local replacement = replace_references(v, name_mapping, name)
|
||||||
|
|
||||||
|
if (replacement ~= v) then
|
||||||
|
changes[k] = replacement;
|
||||||
|
hasChanges = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (not hasChanges) then
|
||||||
|
return object
|
||||||
|
end
|
||||||
|
|
||||||
|
local result = {}
|
||||||
|
|
||||||
|
for k, v in pairs(object) do
|
||||||
|
result[k] = changes[k] or object[k]
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function consume_pending_definitions()
|
||||||
|
local result = pending_definitions
|
||||||
|
consume_pending_definitions = {}
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_definitions(definitions)
|
||||||
|
local name_mapping = {}
|
||||||
|
|
||||||
|
for k, v in pairs(definitions) do
|
||||||
|
populate_name_mapping(v.name, v.data, name_mapping)
|
||||||
|
end
|
||||||
|
|
||||||
|
for k, v in pairs(definitions) do
|
||||||
|
v.data = replace_references(v.data, name_mapping, v.name)
|
||||||
|
end
|
||||||
|
end
|
|
@ -25,6 +25,7 @@
|
||||||
#include "src/materials/MaterialState.h"
|
#include "src/materials/MaterialState.h"
|
||||||
#include "src/materials/MaterialTranslator.h"
|
#include "src/materials/MaterialTranslator.h"
|
||||||
#include "src/StringUtils.h"
|
#include "src/StringUtils.h"
|
||||||
|
#include "src/lua_generator/LuaGenerator.h"
|
||||||
|
|
||||||
void handler(int sig) {
|
void handler(int sig) {
|
||||||
void *array[10];
|
void *array[10];
|
||||||
|
@ -226,6 +227,15 @@ int main(int argc, char *argv[]) {
|
||||||
generateMeshCollider(fileDef, *collisionOutput);
|
generateMeshCollider(fileDef, *collisionOutput);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case FileOutputType::Script:
|
||||||
|
{
|
||||||
|
NodeGroups nodesByGroup(scene);
|
||||||
|
for (auto script : args.mScriptFiles) {
|
||||||
|
std::cout << "Generating definitions from script " << script << std::endl;
|
||||||
|
generateFromLuaScript(script, scene, fileDef, nodesByGroup, settings);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Writing output" << std::endl;
|
std::cout << "Writing output" << std::endl;
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
|
|
||||||
GCC_FLAGS = -Wall -Werror -g -rdynamic -I./yaml-cpp/include
|
GCC_FLAGS = -Wall -Werror -g -rdynamic -I./yaml-cpp/include
|
||||||
|
|
||||||
LINKER_FLAGS = -L./yaml-cpp -lassimp -lyaml-cpp -lpng -ltiff
|
LINKER_FLAGS = -L./yaml-cpp -lassimp -lyaml-cpp -lpng -ltiff -llua -ldl
|
||||||
|
|
||||||
SRC_FILES = main.cpp $(shell find src/ -type f -name '*.cpp')
|
SRC_FILES = main.cpp $(shell find src/ -type f -name '*.cpp')
|
||||||
|
|
||||||
OBJ_FILES = $(patsubst %.cpp, build/%.o, $(SRC_FILES))
|
OBJ_FILES = $(patsubst %.cpp, build/%.o, $(SRC_FILES))
|
||||||
|
|
||||||
|
LUA_SRC_FILES = $(shell find lua/ -type f -name '*.lua')
|
||||||
|
|
||||||
|
LUA_OBJ_FILES = $(patsubst %.lua, build/%.o, $(LUA_SRC_FILES))
|
||||||
|
|
||||||
DEPS = $(patsubst %.cpp, build/%.d, $(SRC_FILES))
|
DEPS = $(patsubst %.cpp, build/%.d, $(SRC_FILES))
|
||||||
|
|
||||||
.PHONY: default
|
.PHONY: default
|
||||||
|
@ -14,13 +18,18 @@ default: skeletool64
|
||||||
|
|
||||||
-include $(DEPS)
|
-include $(DEPS)
|
||||||
|
|
||||||
|
build/lua/%.o: lua/%.lua
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
luac -o $(@:%.o=%.out) $<
|
||||||
|
ld -r -b binary -o $@ $(@:%.o=%.out)
|
||||||
|
|
||||||
build/%.o: %.cpp
|
build/%.o: %.cpp
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
g++ $(GCC_FLAGS) -c $< -o $@
|
g++ $(GCC_FLAGS) -c $< -o $@
|
||||||
$(CC) $(GCC_FLAGS) -MM $^ -MF "$(@:.o=.d)" -MT"$@"
|
$(CC) $(GCC_FLAGS) -MM $^ -MF "$(@:.o=.d)" -MT"$@"
|
||||||
|
|
||||||
skeletool64: $(OBJ_FILES)
|
skeletool64: $(OBJ_FILES) $(LUA_OBJ_FILES)
|
||||||
g++ -g -o skeletool64 $(OBJ_FILES) $(LINKER_FLAGS)
|
g++ -g -o skeletool64 $(OBJ_FILES) $(LUA_OBJ_FILES) $(LINKER_FLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -r build/
|
rm -r build/
|
||||||
|
|
|
@ -57,6 +57,8 @@ bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArgumen
|
||||||
output.mForceMaterialName = curr;
|
output.mForceMaterialName = curr;
|
||||||
} else if (lastParameter == "pallete") {
|
} else if (lastParameter == "pallete") {
|
||||||
output.mForcePallete = curr;
|
output.mForcePallete = curr;
|
||||||
|
} else if (lastParameter == "script") {
|
||||||
|
output.mScriptFiles.push_back(curr);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastParameter = "";
|
lastParameter = "";
|
||||||
|
@ -100,6 +102,9 @@ bool parseCommandLineArguments(int argc, char *argv[], struct CommandLineArgumen
|
||||||
lastParameter = "default-material";
|
lastParameter = "default-material";
|
||||||
} else if (strcmp(curr, "--force-material") == 0) {
|
} else if (strcmp(curr, "--force-material") == 0) {
|
||||||
lastParameter = "force-material";
|
lastParameter = "force-material";
|
||||||
|
} else if (strcmp(curr, "--script") == 0) {
|
||||||
|
output.mOutputType = FileOutputType::Script;
|
||||||
|
lastParameter = "script";
|
||||||
} else {
|
} else {
|
||||||
if (curr[0] == '-') {
|
if (curr[0] == '-') {
|
||||||
hasError = true;
|
hasError = true;
|
||||||
|
|
|
@ -12,6 +12,7 @@ enum class FileOutputType {
|
||||||
Level,
|
Level,
|
||||||
Materials,
|
Materials,
|
||||||
CollisionMesh,
|
CollisionMesh,
|
||||||
|
Script,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CommandLineArguments {
|
struct CommandLineArguments {
|
||||||
|
@ -20,6 +21,7 @@ struct CommandLineArguments {
|
||||||
FileOutputType mOutputType;
|
FileOutputType mOutputType;
|
||||||
std::string mPrefix;
|
std::string mPrefix;
|
||||||
std::vector<std::string> mMaterialFiles;
|
std::vector<std::string> mMaterialFiles;
|
||||||
|
std::vector<std::string> mScriptFiles;
|
||||||
std::string mDefaultMaterial;
|
std::string mDefaultMaterial;
|
||||||
std::string mForceMaterialName;
|
std::string mForceMaterialName;
|
||||||
std::string mForcePallete;
|
std::string mForcePallete;
|
||||||
|
|
|
@ -2,6 +2,15 @@
|
||||||
#include "RenderChunk.h"
|
#include "RenderChunk.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
RenderChunk::RenderChunk(): mBonePair(nullptr, nullptr),
|
||||||
|
mMesh(nullptr),
|
||||||
|
mMeshRoot(nullptr),
|
||||||
|
mAttachedDLIndex(-1),
|
||||||
|
mMaterial(nullptr) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
RenderChunk::RenderChunk(std::pair<Bone*, Bone*> bonePair, std::shared_ptr<ExtendedMesh> mesh, aiNode* meshRoot, Material* material):
|
RenderChunk::RenderChunk(std::pair<Bone*, Bone*> bonePair, std::shared_ptr<ExtendedMesh> mesh, aiNode* meshRoot, Material* material):
|
||||||
mBonePair(bonePair),
|
mBonePair(bonePair),
|
||||||
mMesh(mesh),
|
mMesh(mesh),
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
class RenderChunk {
|
class RenderChunk {
|
||||||
public:
|
public:
|
||||||
|
RenderChunk();
|
||||||
RenderChunk(std::pair<Bone*, Bone*> bonePair, std::shared_ptr<ExtendedMesh> mesh, aiNode* meshRoot, Material* material);
|
RenderChunk(std::pair<Bone*, Bone*> bonePair, std::shared_ptr<ExtendedMesh> mesh, aiNode* meshRoot, Material* material);
|
||||||
RenderChunk(std::pair<Bone*, Bone*> bonePair, int attachedDLIndex, Material* material);
|
RenderChunk(std::pair<Bone*, Bone*> bonePair, int attachedDLIndex, Material* material);
|
||||||
// if bones are the same, chunk cooresponds to a single bone
|
// if bones are the same, chunk cooresponds to a single bone
|
||||||
|
|
|
@ -45,7 +45,7 @@ std::string StringDataChunk::EscapeAndWrapString(const std::string& string) {
|
||||||
if (escapeChar) {
|
if (escapeChar) {
|
||||||
result << '\\' << escapeChar;
|
result << '\\' << escapeChar;
|
||||||
} else {
|
} else {
|
||||||
result << escapeChar;
|
result << currChar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
30
skelatool64/src/lua_generator/LuaBasicTypes.cpp
Normal file
30
skelatool64/src/lua_generator/LuaBasicTypes.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#include "LuaBasicTypes.h"
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const std::string& string) {
|
||||||
|
lua_pushlstring(L, string.c_str(), string.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, std::string& string) {
|
||||||
|
size_t len;
|
||||||
|
const char* str = lua_tolstring(L, -1, &len);
|
||||||
|
string.assign(str, len);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toLua(lua_State* L, int number) {
|
||||||
|
lua_pushinteger(L, number);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, int& number) {
|
||||||
|
number = lua_tointeger(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toLua(lua_State* L, double number) {
|
||||||
|
lua_pushnumber(L, number);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, double& number) {
|
||||||
|
number = lua_tonumber(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
110
skelatool64/src/lua_generator/LuaBasicTypes.h
Normal file
110
skelatool64/src/lua_generator/LuaBasicTypes.h
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
#ifndef __LUA_BASIC_TYPES_H__
|
||||||
|
#define __LUA_BASIC_TYPES_H__
|
||||||
|
|
||||||
|
#include <lua.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const std::string& string);
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, std::string& string);
|
||||||
|
|
||||||
|
void toLua(lua_State* L, int number);
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, int& number);
|
||||||
|
|
||||||
|
void toLua(lua_State* L, double number);
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, double& number);
|
||||||
|
|
||||||
|
template <typename T> void toLua(lua_State* L, const std::vector<T> vector) {
|
||||||
|
lua_createtable(L, vector.size(), 0);
|
||||||
|
|
||||||
|
int tableIndex = lua_gettop(L);
|
||||||
|
|
||||||
|
int index = 1;
|
||||||
|
|
||||||
|
for (const auto& element : vector) {
|
||||||
|
toLua(L, element);
|
||||||
|
lua_seti(L, tableIndex, index);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void fromLua(lua_State* L, std::vector<T>& result) {
|
||||||
|
lua_len(L, -1);
|
||||||
|
|
||||||
|
int length;
|
||||||
|
fromLua(L, length);
|
||||||
|
result.resize(length);
|
||||||
|
|
||||||
|
for (int i = 1; i <= length; ++i) {
|
||||||
|
lua_geti(L, -1, i);
|
||||||
|
fromLua(L, result[i-1]);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void toLua(lua_State* L, const T* array, unsigned count) {
|
||||||
|
lua_createtable(L, count, 0);
|
||||||
|
|
||||||
|
int tableIndex = lua_gettop(L);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < count; ++i) {
|
||||||
|
toLua(L, array[i]);
|
||||||
|
lua_seti(L, tableIndex, i + 1);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename B> void toLua(lua_State* L, const std::pair<A, B>& pair) {
|
||||||
|
lua_createtable(L, 2, 0);
|
||||||
|
|
||||||
|
int tableIndex = lua_gettop(L);
|
||||||
|
|
||||||
|
toLua(L, pair.first);
|
||||||
|
lua_seti(L, tableIndex, 1);
|
||||||
|
|
||||||
|
toLua(L, pair.second);
|
||||||
|
lua_seti(L, tableIndex, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename B> void fromLua(lua_State* L, std::pair<A, B>& pair) {
|
||||||
|
lua_geti(L, -1, 1);
|
||||||
|
fromLua(L, pair.first);
|
||||||
|
lua_geti(L, -1, 2);
|
||||||
|
fromLua(L, pair.second);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> int luaSharedPtrGC(lua_State* L) {
|
||||||
|
std::shared_ptr<T>* ptr = (std::shared_ptr<T>*)luaL_checkudata(L, 1, typeid(std::shared_ptr<T>).name());
|
||||||
|
ptr->~shared_ptr();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void toLua(lua_State* L, std::shared_ptr<T> ptr) {
|
||||||
|
std::shared_ptr<T>* result = (std::shared_ptr<T>*)lua_newuserdata(L, sizeof(std::shared_ptr<T>));
|
||||||
|
|
||||||
|
int resultIndex = lua_gettop(L);
|
||||||
|
|
||||||
|
new(result) std::shared_ptr<T>(ptr);
|
||||||
|
|
||||||
|
if (luaL_newmetatable(L, typeid(std::shared_ptr<T>).name())) {
|
||||||
|
lua_pushcfunction(L, luaSharedPtrGC<T>);
|
||||||
|
lua_setfield(L, -2, "__gc");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_setmetatable(L, resultIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void fromLua(lua_State* L, std::shared_ptr<T>& output) {
|
||||||
|
std::shared_ptr<T>* ptr = (std::shared_ptr<T>*)luaL_checkudata(L, -1, typeid(std::shared_ptr<T>).name());
|
||||||
|
output = *ptr;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
189
skelatool64/src/lua_generator/LuaDefinitionWriter.cpp
Normal file
189
skelatool64/src/lua_generator/LuaDefinitionWriter.cpp
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
#include "LuaDefinitionWriter.h"
|
||||||
|
|
||||||
|
#include "LuaGenerator.h"
|
||||||
|
#include "../StringUtils.h"
|
||||||
|
|
||||||
|
std::unique_ptr<DataChunk> buildDataChunk(lua_State* L);
|
||||||
|
|
||||||
|
std::unique_ptr<DataChunk> buildMacroChunk(lua_State* L) {
|
||||||
|
lua_getfield(L, -1, "name");
|
||||||
|
std::string name = lua_tostring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
std::unique_ptr<MacroDataChunk> result(new MacroDataChunk(name));
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "args");
|
||||||
|
|
||||||
|
int args = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_pushnil(L); /* first key */
|
||||||
|
while (lua_next(L, args) != 0) {
|
||||||
|
result->Add(std::move(buildDataChunk(L)));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<DataChunk> buildStructureChunk(lua_State* L) {
|
||||||
|
int topStart = lua_gettop(L);
|
||||||
|
|
||||||
|
std::unique_ptr<StructureDataChunk> result(new StructureDataChunk());
|
||||||
|
|
||||||
|
lua_pushnil(L); /* first key */
|
||||||
|
while (lua_next(L, topStart) != 0) {
|
||||||
|
int keyType = lua_type(L, -2);
|
||||||
|
if (keyType == LUA_TNUMBER) {
|
||||||
|
result->Add(std::move(buildDataChunk(L)));
|
||||||
|
} else if (keyType == LUA_TSTRING) {
|
||||||
|
result->Add(lua_tostring(L, -2), std::move(buildDataChunk(L)));
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<DataChunk> buildDataChunk(lua_State* L) {
|
||||||
|
int type = lua_type(L, -1);
|
||||||
|
|
||||||
|
if (type == LUA_TNUMBER) {
|
||||||
|
if (lua_isinteger(L, -1))
|
||||||
|
{
|
||||||
|
int result = lua_tointeger(L, -1);
|
||||||
|
return std::unique_ptr<DataChunk>(new PrimitiveDataChunk<int>(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
double result = lua_tonumber(L, -1);
|
||||||
|
return std::unique_ptr<DataChunk>(new PrimitiveDataChunk<double>(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == LUA_TNIL) {
|
||||||
|
return std::unique_ptr<DataChunk>(new PrimitiveDataChunk<int>(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == LUA_TBOOLEAN) {
|
||||||
|
return std::unique_ptr<DataChunk>(new PrimitiveDataChunk<int>(lua_toboolean(L, -1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == LUA_TSTRING) {
|
||||||
|
size_t len;
|
||||||
|
const char* buffer = lua_tolstring(L, -1, &len);
|
||||||
|
std::string bufferAsString(buffer, len);
|
||||||
|
return std::unique_ptr<DataChunk>(new StringDataChunk(bufferAsString));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == LUA_TTABLE) {
|
||||||
|
lua_getglobal(L, "is_raw");
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_copy(L, -3, -1);
|
||||||
|
lua_call(L, 1, 1);
|
||||||
|
if (lua_toboolean(L, -1)) {
|
||||||
|
// pop the bool
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_getfield(L, -1, "value");
|
||||||
|
std::unique_ptr<DataChunk> result(new PrimitiveDataChunk<std::string>(lua_tostring(L, -1)));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_getglobal(L, "is_macro");
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_copy(L, -3, -1);
|
||||||
|
lua_call(L, 1, 1);
|
||||||
|
if (lua_toboolean(L, -1)) {
|
||||||
|
// pop the bool
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return buildMacroChunk(L);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
return buildStructureChunk(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::unique_ptr<DataChunk>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void processCFileDefinition(lua_State* L, CFileDefinition& fileDef, const char* filename) {
|
||||||
|
int topStart = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_getfield(L, topStart, "name");
|
||||||
|
std::string definitionName = lua_tostring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_getfield(L, topStart, "dataType");
|
||||||
|
std::string dataType = lua_tostring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_getfield(L, topStart, "location");
|
||||||
|
std::string location = lua_tostring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
bool isArray = false;
|
||||||
|
|
||||||
|
if (EndsWith(dataType, "[]")) {
|
||||||
|
isArray = true;
|
||||||
|
dataType = dataType.substr(0, dataType.length() - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getfield(L, topStart, "data");
|
||||||
|
std::unique_ptr<DataChunk> dataChunk = buildDataChunk(L);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
std::unique_ptr<FileDefinition> definition(new DataFileDefinition(dataType, definitionName, isArray, location, std::move(dataChunk)));
|
||||||
|
fileDef.AddDefinition(std::move(definition));
|
||||||
|
}
|
||||||
|
|
||||||
|
void dumpDefinitions(lua_State* L, CFileDefinition& fileDef, const char* filename) {
|
||||||
|
int topStart = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_getglobal(L, "consume_pending_definitions");
|
||||||
|
int errcode = lua_pcall(L, 0, 1, 0);
|
||||||
|
|
||||||
|
if (checkLuaError(L, errcode, filename)) {
|
||||||
|
lua_settop(L, topStart);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int definitionArray = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_pushnil(L); /* first key */
|
||||||
|
while (lua_next(L, definitionArray) != 0) {
|
||||||
|
int entry = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_getfield(L, entry, "nameHint");
|
||||||
|
const char* nameHint = lua_tostring(L, -1);
|
||||||
|
std::string name = fileDef.GetUniqueName(nameHint);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_pushstring(L, name.c_str());
|
||||||
|
lua_setfield(L, entry, "name");
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_getglobal(L, "process_definitions");
|
||||||
|
lua_pushnil(L);
|
||||||
|
|
||||||
|
lua_copy(L, definitionArray, -1);
|
||||||
|
|
||||||
|
errcode = lua_pcall(L, 1, LUA_MULTRET, 0);
|
||||||
|
|
||||||
|
if (checkLuaError(L, errcode, filename)) {
|
||||||
|
lua_settop(L, topStart);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, definitionArray);
|
||||||
|
|
||||||
|
lua_pushnil(L); /* first key */
|
||||||
|
while (lua_next(L, topStart + 1) != 0) {
|
||||||
|
processCFileDefinition(L, fileDef, filename);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lua_settop(L, topStart);
|
||||||
|
}
|
9
skelatool64/src/lua_generator/LuaDefinitionWriter.h
Normal file
9
skelatool64/src/lua_generator/LuaDefinitionWriter.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef __LUA_DEFINITON_WRITER_H__
|
||||||
|
#define __LUA_DEFINITON_WRITER_H__
|
||||||
|
|
||||||
|
#include <lua.hpp>
|
||||||
|
#include "../CFileDefinition.h"
|
||||||
|
|
||||||
|
void dumpDefinitions(lua_State* L, CFileDefinition& fileDef, const char* filename);
|
||||||
|
|
||||||
|
#endif
|
54
skelatool64/src/lua_generator/LuaDisplayListSettings.cpp
Normal file
54
skelatool64/src/lua_generator/LuaDisplayListSettings.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include "LuaDisplayListSettings.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "./LuaMesh.h"
|
||||||
|
|
||||||
|
Material* luaGetMaterial(lua_State* L, const DisplayListSettings& defaults) {
|
||||||
|
int materialType = lua_type(L, -1);
|
||||||
|
|
||||||
|
if (materialType == LUA_TSTRING) {
|
||||||
|
auto material = defaults.mMaterials.find(lua_tostring(L, -1));
|
||||||
|
|
||||||
|
if (material != defaults.mMaterials.end()) {
|
||||||
|
return material->second.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (materialType == LUA_TTABLE) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_copy(L, -2, -1);
|
||||||
|
Material* result = nullptr;
|
||||||
|
fromLua(L, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, DisplayListSettings& result, const DisplayListSettings& defaults) {
|
||||||
|
result = defaults;
|
||||||
|
|
||||||
|
int topStart = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_pushnil(L); /* first key */
|
||||||
|
while (lua_next(L, topStart) != 0) {
|
||||||
|
int keyType = lua_type(L, -2);
|
||||||
|
|
||||||
|
if (keyType == LUA_TSTRING) {
|
||||||
|
const char* key = lua_tostring(L, -2);
|
||||||
|
|
||||||
|
if (strcmp(key, "defaultMaterial") == 0) {
|
||||||
|
Material* material = luaGetMaterial(L, defaults);
|
||||||
|
|
||||||
|
if (!material) {
|
||||||
|
luaL_error(L, "invlaid defaultMaterial");
|
||||||
|
}
|
||||||
|
|
||||||
|
result.mDefaultMaterialState = material->mState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
skelatool64/src/lua_generator/LuaDisplayListSettings.h
Normal file
9
skelatool64/src/lua_generator/LuaDisplayListSettings.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef __LUA_DISPLAY_LIST_SETTINGS_H__
|
||||||
|
#define __LUA_DISPLAY_LIST_SETTINGS_H__
|
||||||
|
|
||||||
|
#include <lua.hpp>
|
||||||
|
#include "../DisplayListSettings.h"
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, DisplayListSettings& result, const DisplayListSettings& defaults);
|
||||||
|
|
||||||
|
#endif
|
1
skelatool64/src/lua_generator/LuaFiles.h
Normal file
1
skelatool64/src/lua_generator/LuaFiles.h
Normal file
|
@ -0,0 +1 @@
|
||||||
|
EMIT(definition_writer)
|
92
skelatool64/src/lua_generator/LuaGenerator.cpp
Normal file
92
skelatool64/src/lua_generator/LuaGenerator.cpp
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
#include "LuaGenerator.h"
|
||||||
|
#include "../FileUtils.h"
|
||||||
|
|
||||||
|
#include "LuaDefinitionWriter.h"
|
||||||
|
#include "LuaTransform.h"
|
||||||
|
#include "LuaNodeGroups.h"
|
||||||
|
#include "LuaScene.h"
|
||||||
|
#include "LuaMesh.h"
|
||||||
|
|
||||||
|
#include <lua.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define EMIT(name) extern const char _binary_build_lua_##name##_out_start[]; extern const char _binary_build_lua_##name##_out_end[];
|
||||||
|
#include "LuaFiles.h"
|
||||||
|
#undef EMIT
|
||||||
|
|
||||||
|
struct LuaFile {
|
||||||
|
const char* start;
|
||||||
|
const char* end;
|
||||||
|
const char* name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LuaFile luaFiles[] = {
|
||||||
|
#define EMIT(name) {_binary_build_lua_##name##_out_start, _binary_build_lua_##name##_out_end, "lua/" #name ".lua"},
|
||||||
|
#include "LuaFiles.h"
|
||||||
|
#undef EMIT
|
||||||
|
};
|
||||||
|
|
||||||
|
bool checkLuaError(lua_State *L, int errCode, const char* filename) {
|
||||||
|
if (errCode != LUA_OK) {
|
||||||
|
const char* error = lua_tostring(L, -1);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
std::cerr << "Error running " << filename << ":" << std::endl << error << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Unknown error running " << filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateFromLuaScript(
|
||||||
|
const std::string& filename,
|
||||||
|
const aiScene* scene,
|
||||||
|
CFileDefinition& fileDefinition,
|
||||||
|
NodeGroups& nodeGroups,
|
||||||
|
const DisplayListSettings& settings
|
||||||
|
) {
|
||||||
|
lua_State *L = luaL_newstate();
|
||||||
|
luaL_openlibs(L);
|
||||||
|
generateLuaTransform(L);
|
||||||
|
populateLuaScene(L, scene);
|
||||||
|
populateLuaNodeGroups(L, nodeGroups);
|
||||||
|
populateLuaMesh(L, scene, fileDefinition, settings);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < sizeof(luaFiles) / sizeof(*luaFiles); ++i) {
|
||||||
|
struct LuaFile* file = &luaFiles[i];
|
||||||
|
luaL_loadbuffer(L, file->start, file->end - file->start, file->name);
|
||||||
|
|
||||||
|
int stackSize = lua_gettop(L);
|
||||||
|
int errCode = lua_pcall(L, 0, LUA_MULTRET, 0);
|
||||||
|
if (checkLuaError(L, errCode, file->name)) {
|
||||||
|
lua_close(L);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, stackSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string directory = DirectoryName(filename) + "/?.lua;";
|
||||||
|
|
||||||
|
// set the directory of the script location as a search path
|
||||||
|
lua_getglobal(L, "package");
|
||||||
|
int packageLocation = lua_gettop(L);
|
||||||
|
lua_pushstring(L, directory.c_str());
|
||||||
|
lua_getfield(L, packageLocation, "path");
|
||||||
|
lua_concat(L, 2);
|
||||||
|
lua_setfield(L, packageLocation, "path");
|
||||||
|
|
||||||
|
int errCode = luaL_dofile(L, filename.c_str());
|
||||||
|
if (checkLuaError(L, errCode, filename.c_str())) {
|
||||||
|
lua_close(L);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dumpDefinitions(L, fileDefinition, filename.c_str());
|
||||||
|
|
||||||
|
lua_close(L);
|
||||||
|
}
|
20
skelatool64/src/lua_generator/LuaGenerator.h
Normal file
20
skelatool64/src/lua_generator/LuaGenerator.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef __LUA_GENERATOR_H__
|
||||||
|
#define __LUA_GENERATOR_H__
|
||||||
|
|
||||||
|
#include <lua.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include "../CFileDefinition.h"
|
||||||
|
#include "../DisplayListSettings.h"
|
||||||
|
#include "../definition_generator/DefinitionGenerator.h"
|
||||||
|
|
||||||
|
bool checkLuaError(lua_State *L, int errCode, const char* filename);
|
||||||
|
|
||||||
|
void generateFromLuaScript(
|
||||||
|
const std::string& filename,
|
||||||
|
const aiScene* scene,
|
||||||
|
CFileDefinition& fileDefinition,
|
||||||
|
NodeGroups& nodeGroups,
|
||||||
|
const DisplayListSettings& settings
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
157
skelatool64/src/lua_generator/LuaMesh.cpp
Normal file
157
skelatool64/src/lua_generator/LuaMesh.cpp
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
#include "LuaMesh.h"
|
||||||
|
|
||||||
|
#include "../definition_generator/MeshDefinitionGenerator.h"
|
||||||
|
#include "./LuaBasicTypes.h"
|
||||||
|
#include "./LuaScene.h"
|
||||||
|
#include "../MeshWriter.h"
|
||||||
|
#include "./LuaDisplayListSettings.h"
|
||||||
|
|
||||||
|
void toLua(lua_State* L, Material* material) {
|
||||||
|
lua_createtable(L, 1, 0);
|
||||||
|
|
||||||
|
luaL_getmetatable(L, "Material");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
|
||||||
|
toLua(L, material->mName);
|
||||||
|
lua_setfield(L, -2, "name");
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, material);
|
||||||
|
lua_setfield(L, -2, "ptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, Material *& material) {
|
||||||
|
lua_getfield(L, -1, "ptr");
|
||||||
|
material = (Material*)lua_touserdata(L, -1);
|
||||||
|
lua_pop(L, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void meshToLua(lua_State* L, std::shared_ptr<ExtendedMesh> mesh) {
|
||||||
|
lua_createtable(L, 0, 1);
|
||||||
|
|
||||||
|
toLua(L, mesh);
|
||||||
|
lua_setfield(L, -2, "ptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
void meshFromLua(lua_State* L, std::shared_ptr<ExtendedMesh>& mesh) {
|
||||||
|
lua_getfield(L, -1, "ptr");
|
||||||
|
|
||||||
|
fromLua(L, mesh);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const Bone* bone) {
|
||||||
|
lua_pushlightuserdata(L, const_cast<Bone*>(bone));
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromLua(lua_State*L, Bone *& bone) {
|
||||||
|
bone = (Bone*)lua_touserdata(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const RenderChunk& renderChunk) {
|
||||||
|
lua_createtable(L, 0, 5);
|
||||||
|
|
||||||
|
int tableIndex = lua_gettop(L);
|
||||||
|
|
||||||
|
toLua(L, renderChunk.mBonePair);
|
||||||
|
lua_setfield(L, tableIndex, "bone_pair");
|
||||||
|
|
||||||
|
meshToLua(L, renderChunk.mMesh);
|
||||||
|
lua_setfield(L, tableIndex, "mesh");
|
||||||
|
|
||||||
|
toLua(L, renderChunk.mMeshRoot);
|
||||||
|
lua_setfield(L, tableIndex, "meshRoot");
|
||||||
|
|
||||||
|
toLua(L, renderChunk.mAttachedDLIndex);
|
||||||
|
lua_setfield(L, tableIndex, "attached_dl_index");
|
||||||
|
|
||||||
|
toLua(L, renderChunk.mMaterial);
|
||||||
|
lua_setfield(L, tableIndex, "material");
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, RenderChunk& result) {
|
||||||
|
lua_getfield(L, -1, "bone_pair");
|
||||||
|
fromLua(L, result.mBonePair);
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "mesh");
|
||||||
|
meshFromLua(L, result.mMesh);
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "meshRoot");
|
||||||
|
fromLua(L, result.mMeshRoot);
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "attached_dl_index");
|
||||||
|
fromLua(L, result.mAttachedDLIndex);
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "material");
|
||||||
|
fromLua(L, result.mMaterial);
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int luaBuildRenderChunks(lua_State* L) {
|
||||||
|
const aiScene* scene = (const aiScene*)lua_touserdata(L, lua_upvalueindex(1));
|
||||||
|
CFileDefinition* fileDefinition = (CFileDefinition*)lua_touserdata(L, lua_upvalueindex(2));
|
||||||
|
DisplayListSettings* settings = (DisplayListSettings*)lua_touserdata(L, lua_upvalueindex(3));
|
||||||
|
|
||||||
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
|
|
||||||
|
lua_getfield(L, 1, "ptr");
|
||||||
|
|
||||||
|
aiNode* node = (aiNode*)lua_touserdata(L, -1);
|
||||||
|
|
||||||
|
std::vector<RenderChunk> renderChunks;
|
||||||
|
if (node) {
|
||||||
|
MeshDefinitionGenerator::AppendRenderChunks(scene, node, *fileDefinition, *settings, renderChunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
toLua(L, renderChunks);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int luaGenerateMesh(lua_State* L) {
|
||||||
|
const aiScene* scene = (const aiScene*)lua_touserdata(L, lua_upvalueindex(1));
|
||||||
|
CFileDefinition* fileDefinition = (CFileDefinition*)lua_touserdata(L, lua_upvalueindex(2));
|
||||||
|
DisplayListSettings* settings = (DisplayListSettings*)lua_touserdata(L, lua_upvalueindex(3));
|
||||||
|
|
||||||
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
|
const char* location = luaL_checkstring(L, 2);
|
||||||
|
|
||||||
|
std::vector<RenderChunk> renderChunks;
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_copy(L, 1, -1);
|
||||||
|
fromLua(L, renderChunks);
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
if (lua_gettop(L) >= 3 && lua_type(L, 3) == LUA_TTABLE) {
|
||||||
|
lua_settop(L, 3);
|
||||||
|
DisplayListSettings settingOverride;
|
||||||
|
fromLua(L, settingOverride, *settings);
|
||||||
|
|
||||||
|
result = generateMesh(scene, *fileDefinition, renderChunks, settingOverride, location);
|
||||||
|
} else {
|
||||||
|
result = generateMesh(scene, *fileDefinition, renderChunks, *settings, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
toLua(L, result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void populateLuaMesh(lua_State* L, const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings) {
|
||||||
|
lua_newtable(L);
|
||||||
|
luaL_setmetatable(L, "Material");
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, const_cast<aiScene*>(scene));
|
||||||
|
lua_pushlightuserdata(L, &fileDefinition);
|
||||||
|
lua_pushlightuserdata(L, const_cast<DisplayListSettings*>(&settings));
|
||||||
|
lua_pushcclosure(L, luaBuildRenderChunks, 3);
|
||||||
|
lua_setglobal(L, "generate_render_chunks");
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, const_cast<aiScene*>(scene));
|
||||||
|
lua_pushlightuserdata(L, &fileDefinition);
|
||||||
|
lua_pushlightuserdata(L, const_cast<DisplayListSettings*>(&settings));
|
||||||
|
lua_pushcclosure(L, luaGenerateMesh, 3);
|
||||||
|
lua_setglobal(L, "generate_mesh");
|
||||||
|
}
|
13
skelatool64/src/lua_generator/LuaMesh.h
Normal file
13
skelatool64/src/lua_generator/LuaMesh.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef __LUA_MESH_H__
|
||||||
|
#define __LUA_MESH_H__
|
||||||
|
|
||||||
|
#include <lua.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include "../CFileDefinition.h"
|
||||||
|
#include "../DisplayListSettings.h"
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, Material *& material);
|
||||||
|
|
||||||
|
void populateLuaMesh(lua_State* L, const aiScene* scene, CFileDefinition& fileDefinition, const DisplayListSettings& settings);
|
||||||
|
|
||||||
|
#endif
|
31
skelatool64/src/lua_generator/LuaNodeGroups.cpp
Normal file
31
skelatool64/src/lua_generator/LuaNodeGroups.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "LuaNodeGroups.h"
|
||||||
|
|
||||||
|
#include "LuaBasicTypes.h"
|
||||||
|
#include "LuaScene.h"
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const NodeWithArguments& nodes) {
|
||||||
|
lua_createtable(L, 0, 2);
|
||||||
|
|
||||||
|
int tableIndex = lua_gettop(L);
|
||||||
|
|
||||||
|
toLua(L, nodes.arguments);
|
||||||
|
lua_setfield(L, tableIndex, "arguments");
|
||||||
|
|
||||||
|
toLua(L, nodes.node);
|
||||||
|
lua_setfield(L, tableIndex, "node");
|
||||||
|
}
|
||||||
|
|
||||||
|
int luaNodesForType(lua_State* L) {
|
||||||
|
std::string prefix = luaL_checkstring(L, 1);
|
||||||
|
NodeGroups* nodeGroups = (NodeGroups*)lua_touserdata(L, lua_upvalueindex(1));
|
||||||
|
|
||||||
|
std::vector<NodeWithArguments> result = nodeGroups->NodesForType(prefix);
|
||||||
|
toLua(L, result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void populateLuaNodeGroups(lua_State* L, NodeGroups& nodeGroups) {
|
||||||
|
lua_pushlightuserdata(L, (NodeGroups*)&nodeGroups);
|
||||||
|
lua_pushcclosure(L, luaNodesForType, 1);
|
||||||
|
lua_setglobal(L, "nodes_for_type");
|
||||||
|
}
|
9
skelatool64/src/lua_generator/LuaNodeGroups.h
Normal file
9
skelatool64/src/lua_generator/LuaNodeGroups.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef __LUA_NODE_GROUPS_H__
|
||||||
|
#define __LUA_NODE_GROUPS_H__
|
||||||
|
|
||||||
|
#include <lua.hpp>
|
||||||
|
#include "../definition_generator/DefinitionGenerator.h"
|
||||||
|
|
||||||
|
void populateLuaNodeGroups(lua_State* L, NodeGroups& nodeGroups);
|
||||||
|
|
||||||
|
#endif
|
79
skelatool64/src/lua_generator/LuaScene.cpp
Normal file
79
skelatool64/src/lua_generator/LuaScene.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include "LuaScene.h"
|
||||||
|
|
||||||
|
#include "LuaBasicTypes.h"
|
||||||
|
#include "LuaTransform.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const aiNode* node) {
|
||||||
|
if (!node) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if node ia already built in the cache
|
||||||
|
lua_getglobal(L, "node_cache");
|
||||||
|
int nodeCache = lua_gettop(L);
|
||||||
|
lua_pushlightuserdata(L, const_cast<aiNode*>(node));
|
||||||
|
lua_gettable(L, nodeCache);
|
||||||
|
|
||||||
|
if (!lua_isnil(L, -1)) {
|
||||||
|
lua_remove(L, nodeCache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_createtable(L, 0, 1);
|
||||||
|
int tableIndex = lua_gettop(L);
|
||||||
|
luaL_getmetatable(L, "aiNode");
|
||||||
|
lua_setmetatable(L, tableIndex);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, const_cast<aiNode*>(node));
|
||||||
|
lua_setfield(L, tableIndex, "ptr");
|
||||||
|
|
||||||
|
toLua(L, node->mName.C_Str());
|
||||||
|
lua_setfield(L, tableIndex, "name");
|
||||||
|
|
||||||
|
toLua(L, node->mTransformation);
|
||||||
|
lua_setfield(L, tableIndex, "transformation");
|
||||||
|
|
||||||
|
// save node into the cache before building related nodes
|
||||||
|
lua_pushlightuserdata(L, const_cast<aiNode*>(node));
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_copy(L, tableIndex, -1);
|
||||||
|
lua_settable(L, nodeCache);
|
||||||
|
|
||||||
|
toLua(L, node->mParent);
|
||||||
|
lua_setfield(L, tableIndex, "parent");
|
||||||
|
|
||||||
|
toLua(L, node->mChildren, node->mNumChildren);
|
||||||
|
lua_setfield(L, tableIndex, "children");
|
||||||
|
|
||||||
|
lua_remove(L, nodeCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, aiNode *& node) {
|
||||||
|
lua_getfield(L, -1, "ptr");
|
||||||
|
node = (aiNode*)lua_touserdata(L, -1);
|
||||||
|
lua_pop(L, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const aiScene* scene) {
|
||||||
|
lua_createtable(L, 0, 1);
|
||||||
|
int tableIndex = lua_gettop(L);
|
||||||
|
luaL_getmetatable(L, "aiScene");
|
||||||
|
lua_setmetatable(L, tableIndex);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, const_cast<aiScene*>(scene));
|
||||||
|
lua_setfield(L, tableIndex, "ptr");
|
||||||
|
|
||||||
|
toLua(L, scene->mRootNode);
|
||||||
|
lua_setfield(L, tableIndex, "root");
|
||||||
|
}
|
||||||
|
|
||||||
|
void populateLuaScene(lua_State* L, const aiScene* scene) {
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setglobal(L, "node_cache");
|
||||||
|
|
||||||
|
toLua(L, scene);
|
||||||
|
lua_setglobal(L, "scene");
|
||||||
|
}
|
13
skelatool64/src/lua_generator/LuaScene.h
Normal file
13
skelatool64/src/lua_generator/LuaScene.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef __LUA_SCENE_H__
|
||||||
|
#define __LUA_SCENE_H__
|
||||||
|
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <lua.hpp>
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const aiNode* node);
|
||||||
|
|
||||||
|
void fromLua(lua_State* L, aiNode *& node);
|
||||||
|
|
||||||
|
void populateLuaScene(lua_State* L, const aiScene* scene);
|
||||||
|
|
||||||
|
#endif
|
15
skelatool64/src/lua_generator/LuaTransform.cpp
Normal file
15
skelatool64/src/lua_generator/LuaTransform.cpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include "LuaTransform.h"
|
||||||
|
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const aiMatrix4x4& matrix) {
|
||||||
|
aiMatrix4x4* result = (aiMatrix4x4*)lua_newuserdata(L, sizeof(aiMatrix4x4));
|
||||||
|
new(result) aiMatrix4x4(matrix);
|
||||||
|
|
||||||
|
luaL_getmetatable(L, "aiMatrix4x4");
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateLuaTransform(lua_State* L) {
|
||||||
|
luaL_newmetatable(L, "aiMatrix4x4");
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
11
skelatool64/src/lua_generator/LuaTransform.h
Normal file
11
skelatool64/src/lua_generator/LuaTransform.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef __LUA_TRANSFORM_H__
|
||||||
|
#define __LUA_TRANSFORM_H__
|
||||||
|
|
||||||
|
#include <lua.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
|
void toLua(lua_State* L, const aiMatrix4x4& matrix);
|
||||||
|
|
||||||
|
void generateLuaTransform(lua_State* L);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue