Skip to content

Commit 45cc2fc

Browse files
authored
Merge pull request #10 from korarei/refactor/lua
Refactor: Update module to be loadable via require in Lua
2 parents a9a7d27 + db60199 commit 45cc2fc

File tree

13 files changed

+805
-290
lines changed

13 files changed

+805
-290
lines changed

.github/workflows/releaser.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ jobs:
2121
with:
2222
arch: x64
2323

24+
- name: Install LuaJIT
25+
uses: leafo/gh-actions-lua@v12
26+
with:
27+
luaVersion: 'luajit-2.1'
28+
2429
- name: Build
2530
run: |
2631
cd ${{ github.workspace }}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
**/__pycache__/
22
**/build/
3-
.vscode/
3+
.vscode/
4+
.lua/

dll_src/CMakeLists.txt

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,49 @@
11
cmake_minimum_required(VERSION 3.20.0)
22
project(ObjectMotionBlur_LK VERSION 0.2.1 LANGUAGES CXX)
33

4+
# Path Settings.
5+
set(LUA_DIR "${CMAKE_SOURCE_DIR}/../.lua")
6+
set(LUAJIT_DEF "${CMAKE_SOURCE_DIR}/luajit/luajit.def")
7+
set(LUAJIT_LIB "${CMAKE_CURRENT_BINARY_DIR}/luajit/luajit.lib")
8+
9+
# Generate the luajit.lib
10+
if(MSVC)
11+
add_custom_command(
12+
OUTPUT ${LUAJIT_LIB}
13+
COMMAND lib /DEF:${LUAJIT_DEF} /OUT:${LUAJIT_LIB} /MACHINE:X64
14+
DEPENDS ${LUAJIT_DEF}
15+
VERBATIM
16+
)
17+
18+
add_custom_target(gen_luajit_lib DEPENDS ${LUAJIT_LIB})
19+
endif()
20+
21+
# Importing Lua Libraries.
22+
add_library(luajit SHARED IMPORTED)
23+
set_target_properties(luajit PROPERTIES
24+
IMPORTED_IMPLIB "${LUAJIT_LIB}"
25+
INTERFACE_INCLUDE_DIRECTORIES "${LUA_DIR}/include/luajit-2.1"
26+
)
27+
428
# Main target definition.
529
add_library(${PROJECT_NAME} SHARED
30+
main.def
631
main.cpp
732
transform_utils.cpp
33+
lua_func.cpp
834
)
935

1036
# Def file specification.
1137
set_target_properties(${PROJECT_NAME} PROPERTIES
12-
LINK_FLAGS "/DEF:${CMAKE_CURRENT_SOURCE_DIR}/main.def"
1338
PREFIX ""
1439
)
1540

41+
# Library Link.
42+
add_dependencies(${PROJECT_NAME} gen_luajit_lib)
43+
target_link_libraries(${PROJECT_NAME} PRIVATE
44+
luajit
45+
)
46+
1647
# C++ version specification.
1748
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
1849

@@ -44,25 +75,4 @@ if (MSVC)
4475
set_target_properties(${PROJECT_NAME} PROPERTIES
4576
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
4677
)
47-
# Functionality has not been confirmed.
48-
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
49-
target_compile_options(${PROJECT_NAME} PRIVATE
50-
-Wall
51-
-Wextra
52-
-Wpedantic
53-
54-
# Release-only
55-
$<$<CONFIG:Release>:-O3>
56-
$<$<CONFIG:Release>:-ffunction-sections>
57-
$<$<CONFIG:Release>:-fdata-sections>
58-
59-
# Debug-only
60-
$<$<CONFIG:Debug>:-O0>
61-
$<$<CONFIG:Debug>:-g>
62-
)
63-
64-
target_link_options(${PROJECT_NAME} PRIVATE
65-
$<$<CONFIG:Release>:-Wl,--gc-sections>
66-
$<$<CONFIG:Debug>:-g>
67-
)
68-
endif()
78+
endif()

dll_src/geo_utils.hpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include <cstddef>
55
#include <cstdint>
66
#include <map>
7-
#include <mutex>
87
#include <unordered_map>
98
#include <vector>
109

@@ -16,7 +15,7 @@ class GeoMap {
1615
constexpr GeoMap() noexcept = default;
1716
constexpr ~GeoMap() noexcept = default;
1817

19-
constexpr void resize(std::size_t hash, std::size_t idx, std::size_t num, std::uint32_t mode) noexcept {
18+
constexpr void resize(std::size_t hash, std::size_t idx, std::size_t num, std::uint32_t mode) {
2019
if (mode == 0u) {
2120
clear(hash);
2221
return;
@@ -32,15 +31,16 @@ class GeoMap {
3231
list.resize(num);
3332
}
3433

35-
auto &block_map = list[idx];
34+
auto &block_map = list.at(idx);
35+
36+
if (mode == 1u || block_map.size() == 1)
37+
return;
3638

37-
if (auto it = block_map.find(0); mode == 2u && it != block_map.end() && block_map.size() != 1) {
39+
if (auto it = block_map.find(0); it != block_map.end()) {
3840
auto node = block_map.extract(it);
3941
BlockMap{}.swap(block_map);
4042
block_map.insert(std::move(node));
4143
}
42-
43-
return;
4444
}
4545

4646
constexpr void write(std::size_t hash, std::size_t idx, std::size_t pos, const Geo &geo) noexcept {
@@ -55,14 +55,33 @@ class GeoMap {
5555
return;
5656

5757
auto &block = list[idx][id];
58+
59+
if (block[offset].is_cached(geo))
60+
return;
61+
62+
block[offset] = geo;
63+
}
64+
65+
constexpr void overwrite(std::size_t hash, std::size_t idx, std::size_t pos, const Geo &geo) noexcept {
66+
const auto [id, offset] = calc_block_pos(pos);
67+
68+
auto it_hash = map.find(hash);
69+
if (it_hash == map.end())
70+
return;
71+
72+
auto &list = it_hash->second;
73+
if (idx >= list.size())
74+
return;
75+
76+
auto &block = list[idx][id];
77+
5878
block[offset] = geo;
59-
return;
6079
}
6180

6281
[[nodiscard]] constexpr const Geo *read(std::size_t hash, std::size_t idx, std::size_t pos) const noexcept {
6382
const auto [id, offset] = calc_block_pos(pos);
6483

65-
if (auto block = get_block(hash, idx, id); block && (*block)[offset].get_flag())
84+
if (auto block = get_block(hash, idx, id); block && (*block)[offset].is_valid())
6685
return &(*block)[offset];
6786
else
6887
return nullptr;
@@ -78,7 +97,6 @@ class GeoMap {
7897
auto &list = it_hash->second;
7998
std::vector<BlockMap>{}.swap(list);
8099
map.erase(hash);
81-
return;
82100
}
83101

84102
private:

dll_src/lua_func.cpp

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#include "lua_func.hpp"
2+
3+
#include <algorithm>
4+
5+
Obj::Obj(lua_State *L) : L(L) {
6+
lua_getglobal(L, "obj");
7+
obj_ref = luaL_ref(L, LUA_REGISTRYINDEX);
8+
}
9+
10+
Obj::~Obj() { luaL_unref(L, LUA_REGISTRYINDEX, obj_ref); }
11+
12+
Param
13+
Obj::get_param() {
14+
constexpr float e = 1.0e-4f;
15+
16+
float shutter_angle = static_cast<float>(std::clamp(get_number(2, 180), 0.0, 360.0));
17+
std::uint32_t render_smp_lim = static_cast<std::uint32_t>(std::max(get_integer(3, 256ll), 1ll));
18+
std::uint32_t preview_smp_lim = static_cast<std::uint32_t>(std::max(get_integer(4, 0ll), 0ll));
19+
std::uint32_t ext = static_cast<std::uint32_t>(std::clamp(get_integer(5, 2ll), 0ll, 2ll));
20+
bool resize = get_boolean(6, true);
21+
std::uint32_t geo_cache = static_cast<std::uint32_t>(std::clamp(get_integer(7, 0ll), 0ll, 2ll));
22+
std::uint32_t geo_ctrl = static_cast<std::uint32_t>(std::clamp(get_integer(8, 0ll), 0ll, 3ll));
23+
float mix = static_cast<float>(std::clamp(get_number(9, 0.0) * 0.01, 0.0, 1.0));
24+
bool print_info = get_boolean(10, false);
25+
26+
std::uint32_t smp_lim = (!preview_smp_lim || get_saving()) ? render_smp_lim : preview_smp_lim;
27+
bool is_valid = shutter_angle > e && smp_lim > 1u;
28+
29+
return Param{get_string(1, "motion_blur"),
30+
shutter_angle,
31+
smp_lim,
32+
ext,
33+
resize,
34+
geo_cache,
35+
geo_ctrl,
36+
mix,
37+
print_info,
38+
is_valid};
39+
}
40+
41+
Input
42+
Obj::get_input(std::uint32_t ext) {
43+
constexpr std::array<const char *, 6> fields{"cx", "cy", "ox", "oy", "rz", "zoom"};
44+
constexpr std::array<const char *, 6> tracks{"cx", "cy", "x", "y", "rz", "zoom"};
45+
46+
Input input{};
47+
48+
lua_rawgeti(L, LUA_REGISTRYINDEX, obj_ref);
49+
50+
lua_getfield(L, -1, "getpixel");
51+
lua_call(L, 0, 2);
52+
input.res = Vec2<float>(static_cast<float>(lua_tonumber(L, -2)), static_cast<float>(lua_tonumber(L, -1)));
53+
lua_pop(L, 2);
54+
55+
input.obj_id = static_cast<std::size_t>(get_integer(11, 0ll));
56+
lua_getfield(L, -1, "index");
57+
lua_getfield(L, -2, "num");
58+
input.obj_idx = static_cast<std::size_t>(lua_tointeger(L, -2));
59+
input.obj_num = static_cast<std::size_t>(lua_tointeger(L, -1));
60+
lua_pop(L, 2);
61+
62+
lua_getfield(L, -1, "frame");
63+
lua_getfield(L, -2, "totalframe");
64+
lua_getfield(L, -3, "framerate");
65+
input.frame = static_cast<std::size_t>(lua_tointeger(L, -3));
66+
std::size_t total_frame = static_cast<std::size_t>(lua_tointeger(L, -2));
67+
const double fps = lua_tonumber(L, -1);
68+
lua_pop(L, 3);
69+
70+
input.is_last = {input.obj_idx == input.obj_num - 1, input.frame == total_frame - 1};
71+
72+
const double dt = 1.0 / fps;
73+
input.geo_curr.set_state(true, input.frame);
74+
75+
for (std::size_t i = 0; i < 6; ++i) {
76+
lua_getfield(L, -1, fields[i]);
77+
lua_getfield(L, -2, "getvalue");
78+
lua_pushstring(L, tracks[i]);
79+
lua_call(L, 1, 1);
80+
input.geo_curr[i] = static_cast<float>(lua_tonumber(L, -2));
81+
input.tf_curr[i] = static_cast<float>(lua_tonumber(L, -1));
82+
lua_pop(L, 2);
83+
}
84+
85+
if (ext && !input.frame) {
86+
switch (ext) {
87+
case 1:
88+
for (std::size_t i = 0; i < 6; ++i) {
89+
lua_getfield(L, -1, "getvalue");
90+
lua_pushstring(L, tracks[i]);
91+
lua_pushnumber(L, dt);
92+
lua_call(L, 2, 1);
93+
const double v1 = lua_tonumber(L, -1);
94+
input.tf_prev[i] = static_cast<float>(input.tf_curr[i] * 2.0 - v1);
95+
lua_pop(L, 1);
96+
}
97+
break;
98+
case 2: {
99+
const double dt2 = dt * 2.0;
100+
for (std::size_t i = 0; i < 6; ++i) {
101+
lua_getfield(L, -1, "getvalue");
102+
lua_pushstring(L, tracks[i]);
103+
lua_pushnumber(L, dt);
104+
lua_call(L, 2, 1);
105+
lua_getfield(L, -2, "getvalue");
106+
lua_pushstring(L, tracks[i]);
107+
lua_pushnumber(L, dt2);
108+
lua_call(L, 2, 1);
109+
const double v1 = lua_tonumber(L, -2);
110+
const double v2 = lua_tonumber(L, -1);
111+
input.tf_prev[i] = static_cast<float>(input.tf_curr[i] * 3.0 - v1 * 3.0 + v2);
112+
lua_pop(L, 2);
113+
}
114+
} break;
115+
default:
116+
input.tf_prev = input.tf_curr;
117+
break;
118+
}
119+
} else if (input.frame) {
120+
lua_getfield(L, -1, "time");
121+
const double time_prev = lua_tonumber(L, -1) - dt;
122+
lua_pop(L, 1);
123+
124+
for (std::size_t i = 0; i < 6; ++i) {
125+
lua_getfield(L, -1, "getvalue");
126+
lua_pushstring(L, tracks[i]);
127+
lua_pushnumber(L, time_prev);
128+
lua_call(L, 2, 1);
129+
input.tf_prev[i] = static_cast<float>(lua_tonumber(L, -1));
130+
lua_pop(L, 1);
131+
}
132+
}
133+
134+
input.pivot = input.tf_curr.get_center() + input.geo_curr.get_center();
135+
136+
lua_pop(L, 1);
137+
return input;
138+
}
139+
140+
bool
141+
Obj::get_saving() {
142+
lua_rawgeti(L, LUA_REGISTRYINDEX, obj_ref);
143+
lua_getfield(L, -1, "getinfo");
144+
lua_pushstring(L, "saving");
145+
lua_call(L, 1, 1);
146+
bool saving = lua_toboolean(L, -1);
147+
lua_pop(L, 2);
148+
return saving;
149+
}
150+
151+
void
152+
Obj::resize(const std::array<Vec2<float>, 2> &margin, const Vec2<float> &center) {
153+
lua_rawgeti(L, LUA_REGISTRYINDEX, obj_ref);
154+
lua_getfield(L, -1, "effect");
155+
lua_pushstring(L, "領域拡張");
156+
lua_pushstring(L, "");
157+
lua_pushinteger(L, static_cast<lua_Integer>(margin[0].get_y()));
158+
lua_pushstring(L, "");
159+
lua_pushinteger(L, static_cast<lua_Integer>(margin[1].get_y()));
160+
lua_pushstring(L, "");
161+
lua_pushinteger(L, static_cast<lua_Integer>(margin[0].get_x()));
162+
lua_pushstring(L, "");
163+
lua_pushinteger(L, static_cast<lua_Integer>(margin[1].get_x()));
164+
lua_call(L, 9, 0);
165+
166+
lua_pushnumber(L, center.get_x());
167+
lua_setfield(L, -2, "cx");
168+
lua_pushnumber(L, center.get_y());
169+
lua_setfield(L, -2, "cy");
170+
171+
lua_pop(L, 1);
172+
}
173+
174+
void
175+
Obj::pixel_shader(const std::string &name, const std::vector<float> &constants) {
176+
lua_rawgeti(L, LUA_REGISTRYINDEX, obj_ref);
177+
lua_getfield(L, -1, "pixelshader");
178+
lua_pushstring(L, name.c_str());
179+
lua_pushstring(L, "object");
180+
lua_pushstring(L, "object");
181+
182+
lua_newtable(L);
183+
for (int i = 0; i < constants.size(); ++i) {
184+
lua_pushnumber(L, constants[i]);
185+
lua_rawseti(L, -2, i + 1);
186+
}
187+
188+
lua_call(L, 4, 0);
189+
lua_pop(L, 1);
190+
}
191+
192+
void
193+
Obj::print(const std::string &str) {
194+
lua_getglobal(L, "debug_print");
195+
lua_pushstring(L, str.c_str());
196+
lua_call(L, 1, 0);
197+
}

0 commit comments

Comments
 (0)