blob: ae9fcbdc5837d03cd6b926602e43c9434df4bb7c [file] [log] [blame] [edit]
#ifdef WITH_RIVE_SCRIPTING
#include "rive/lua/rive_lua_libs.hpp"
#include "lualib.h"
using namespace rive;
static int vec2d_index(lua_State* L)
{
const float* vec = luaL_checkvector(L, 1);
size_t namelen = 0;
const char* name = luaL_checklstring(L, 2, &namelen);
if (namelen == 1)
{
switch (name[0])
{
case 'x':
case '1':
lua_pushnumber(L, vec[0]);
return 1;
case 'y':
case '2':
lua_pushnumber(L, vec[1]);
return 1;
default:
break;
}
}
luaL_error(L, "'%s' is not a valid index of Vec2D", name);
return 0;
}
static int vec2d_length(lua_State* L)
{
auto vec = lua_checkvec2d(L, 1);
lua_pushnumber(L, vec->length());
return 1;
}
static int vec2d_normalized(lua_State* L)
{
auto vec = lua_checkvec2d(L, 1);
lua_pushvec2d(L, vec->normalized());
return 1;
}
static int vec2d_lengthSquared(lua_State* L)
{
auto vec = lua_checkvec2d(L, 1);
lua_pushnumber(L, vec->lengthSquared());
return 1;
}
static int vec2d_distance(lua_State* L)
{
auto lhs = lua_checkvec2d(L, 1);
auto rhs = lua_checkvec2d(L, 2);
lua_pushnumber(L, Vec2D::distance(*lhs, *rhs));
return 1;
}
static int vec2d_distanceSquared(lua_State* L)
{
auto lhs = lua_checkvec2d(L, 1);
auto rhs = lua_checkvec2d(L, 2);
lua_pushnumber(L, Vec2D::distanceSquared(*lhs, *rhs));
return 1;
}
static int vec2d_dot(lua_State* L)
{
auto lhs = lua_checkvec2d(L, 1);
auto rhs = lua_checkvec2d(L, 2);
lua_pushnumber(L, Vec2D::dot(*lhs, *rhs));
return 1;
}
static int vec2d_lerp(lua_State* L)
{
auto lhs = lua_checkvec2d(L, 1);
auto rhs = lua_checkvec2d(L, 2);
float factor = float(luaL_checknumber(L, 3));
lua_pushvec2d(L, Vec2D::lerp(*lhs, *rhs, factor));
return 1;
}
static int vec2d_xy(lua_State* L)
{
float x = (float)lua_tonumber(L, 1);
float y = (float)lua_tonumber(L, 2);
lua_pushvector2(L, x, y);
return 1;
}
static int vec2d_origin(lua_State* L)
{
lua_pushvector2(L, 0.0f, 0.0f);
return 1;
}
static int vec2d_namecall(lua_State* L)
{
int atom;
const char* str = lua_namecallatom(L, &atom);
if (str != nullptr)
{
switch (atom)
{
case (int)LuaAtoms::length:
return vec2d_length(L);
case (int)LuaAtoms::lengthSquared:
return vec2d_lengthSquared(L);
case (int)LuaAtoms::normalized:
return vec2d_normalized(L);
case (int)LuaAtoms::distance:
return vec2d_distance(L);
case (int)LuaAtoms::distanceSquared:
return vec2d_distanceSquared(L);
case (int)LuaAtoms::dot:
return vec2d_dot(L);
case (int)LuaAtoms::lerp:
return vec2d_lerp(L);
}
}
luaL_error(L, "%s is not a valid method of Vec2D", luaL_checkstring(L, 1));
return 0;
}
static const luaL_Reg vec2dStaticMethods[] = {
{"distance", vec2d_distance},
{"distanceSquared", vec2d_distanceSquared},
{"dot", vec2d_dot},
{"lerp", vec2d_lerp},
{"xy", vec2d_xy},
{"origin", vec2d_origin},
{nullptr, nullptr}};
int luaopen_rive_vec2d(lua_State* L)
{
luaL_register(L, "Vec2D", vec2dStaticMethods);
// create metatable for T
lua_createtable(L, 0, 1);
// Dupe the metatable on the stack
lua_pushvalue(L, -1);
// Add a vector
lua_pushvector(L, 0.0f, 0.0f, 0.0f);
// Move it before the metatable
lua_insert(L, -2);
// Set metatable on the vector (globally sets the metatable for all
// vectors).
lua_setmetatable(L, -2);
// pop vector
lua_pop(L, 1);
lua_pushcfunction(L, vec2d_index, nullptr);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, vec2d_namecall, nullptr);
lua_setfield(L, -2, "__namecall");
lua_setreadonly(L, -1, true);
lua_pop(L, 1); // pop the metatable
return 1;
}
#endif