mirror of
https://github.com/UberGames/rpgxEF.git
synced 2024-11-10 15:21:34 +00:00
452 lines
7.9 KiB
C
452 lines
7.9 KiB
C
// vector lib for Lua
|
|
|
|
#include "g_lua.h"
|
|
|
|
#if(defined(CG_LUA) || defined(G_LUA))
|
|
|
|
#include "lua.h"
|
|
#include "lauxlib.h"
|
|
#include "lualib.h"
|
|
|
|
/***
|
|
A module implementing vectors.
|
|
@module vector
|
|
*/
|
|
|
|
/***
|
|
Create a new vector.
|
|
@function New
|
|
@return A new vector with x = y = z = 0.
|
|
*/
|
|
static int Vector_New(lua_State *L) {
|
|
vec_t *v;
|
|
|
|
v = (vec_t *)lua_newuserdata(L, sizeof(vec3_t));
|
|
|
|
luaL_getmetatable(L, "vector");
|
|
lua_setmetatable(L, -2);
|
|
|
|
VectorClear(v);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Create a new vector with the given values.
|
|
@function Construct
|
|
@param x X value.
|
|
@param y Y value.
|
|
@param z Z value.
|
|
@return A new vector with given values for x, y, and z.
|
|
*/
|
|
static int Vector_Construct(lua_State *L) {
|
|
vec_t *v;
|
|
|
|
v = (vec_t *)lua_newuserdata(L, sizeof(vec3_t));
|
|
|
|
luaL_getmetatable(L, "vector");
|
|
lua_setmetatable(L, -2);
|
|
|
|
v[0] = luaL_optnumber(L, 1, 0);
|
|
v[1] = luaL_optnumber(L, 2, 0);
|
|
v[2] = luaL_optnumber(L, 3, 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Set vector to given values.
|
|
@function Set
|
|
@param x New x value.
|
|
@param y New y value.
|
|
@param z New z value.
|
|
*/
|
|
static int Vector_Set(lua_State *L) {
|
|
vec_t *v;
|
|
|
|
v = Lua_GetVector(L, 1);
|
|
|
|
v[0] = luaL_optnumber(L, 2, 0);
|
|
v[0] = luaL_optnumber(L, 3, 0);
|
|
v[0] = luaL_optnumber(L, 4, 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Clears the vector which means x = y = z = 0.
|
|
@function Clear
|
|
*/
|
|
static int Vector_Clear(lua_State * L)
|
|
{
|
|
vec_t *a;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
|
|
VectorClear(a);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Add vector b to vector a and return the result.
|
|
@function Add
|
|
@param a Vector.
|
|
@param b Vector.
|
|
@return Result.
|
|
*/
|
|
static int Vector_Add(lua_State *L) {
|
|
vec_t *a, *b;
|
|
vec3_t c;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
b = Lua_GetVector(L, 2);
|
|
|
|
VectorAdd(a, b, c);
|
|
|
|
Lua_PushVector(L, c);
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Substract vector b from vector a and return the result.
|
|
@function Subtract
|
|
@param a Vector.
|
|
@param b Vector.
|
|
@return Result.
|
|
*/
|
|
static int Vector_Subtract(lua_State *L) {
|
|
vec_t *a, *b;
|
|
vec3_t c;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
b = Lua_GetVector(L, 2);
|
|
|
|
VectorSubtract(a, b, c);
|
|
|
|
Lua_PushVector(L, c);
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Scale vector a by value b and return the result.
|
|
@function Scale.
|
|
@param a Vector.
|
|
@param b Scaling factor.
|
|
@return Result.
|
|
*/
|
|
static int Vector_Scale(lua_State *L) {
|
|
vec_t *a, b;
|
|
vec3_t c;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
b = luaL_checknumber(L, 2);
|
|
|
|
VectorScale(a,b,c);
|
|
|
|
Lua_PushVector(L, c);
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Get the length of the vector.
|
|
@function Length
|
|
@return Length of given vector.
|
|
*/
|
|
static int Vector_Length(lua_State *L) {
|
|
vec_t *a;
|
|
vec_t len;
|
|
|
|
a = Lua_GetVector(L,1);
|
|
|
|
len = VectorLength(a);
|
|
lua_pushnumber(L, len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Normalize a vector.
|
|
@function Normalize
|
|
@return Vector length.
|
|
*/
|
|
static int Vector_Normalize(lua_State *L) {
|
|
vec_t *a;
|
|
vec_t len;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
|
|
len = VectorNormalize(a);
|
|
lua_pushnumber(L, len);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Normalize a vector (fast method).
|
|
@function NormalizeFast
|
|
@return Vector length.
|
|
*/
|
|
static int Vector_NormalizeFast(lua_State *L) {
|
|
vec_t *a;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
|
|
VectorNormalizeFast(a);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Rotates point around a given vector.
|
|
@function RotatePointAround
|
|
@param dir Vector to rotate around (must be normalized).
|
|
@param point Point to be rotated.
|
|
@param degrees How many degrees to rotate.
|
|
@param dest Point after rotation.
|
|
*/
|
|
static int Vector_RotatePointAround(lua_State *L) {
|
|
vec_t *dst, *dir, *point;
|
|
vec_t degrees;
|
|
|
|
dst = Lua_GetVector(L, 1);
|
|
dir = Lua_GetVector(L, 2);
|
|
point = Lua_GetVector(L, 3);
|
|
degrees = luaL_checknumber(L, 4);
|
|
|
|
RotatePointAroundVector(dst, dir, point, degrees);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Finds a vector perpendicular to the source vector.
|
|
@function Perpendicular
|
|
@param src Source vector.
|
|
@param dest A vector that is perpendicular to src (the result is stored here)
|
|
*/
|
|
static int Vector_Perpendicular(lua_State *L) {
|
|
vec_t *dst, *src;
|
|
|
|
dst = Lua_GetVector(L, 1);
|
|
src = Lua_GetVector(L, 2);
|
|
|
|
PerpendicularVector(dst, src);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Convert a vector to angles.
|
|
@function VecToAngles
|
|
@param vector Vector.
|
|
@param angles Vector the results are stored in.
|
|
*/
|
|
static int Vector_VecToAngles(lua_State *L) {
|
|
vec_t *v, *t;
|
|
|
|
v = Lua_GetVector(L, 1);
|
|
t = Lua_GetVector(L, 2);
|
|
|
|
vectoangles(v, t);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***
|
|
Calculate forward, right, and up vectors from given angles.
|
|
@function AngleVectors
|
|
@param angles Angles.
|
|
@param fwd Vector to store forward.
|
|
@param right Vector to store right.
|
|
@param up Vector to store up.
|
|
*/
|
|
static int Vector_AngleVectors(lua_State *L) {
|
|
vec_t *v, *fwd, *right, *up;
|
|
|
|
v = Lua_GetVector(L, 1);
|
|
fwd = Lua_GetVector(L, 2);
|
|
right = Lua_GetVector(L, 3);
|
|
up = Lua_GetVector(L, 4);
|
|
|
|
AngleVectors(v, fwd, right, up);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int Vector_Index(lua_State *L) {
|
|
vec_t *v;
|
|
const char *i;
|
|
|
|
v = Lua_GetVector(L, 1);
|
|
i = luaL_checkstring(L, 2);
|
|
|
|
switch(*i) {
|
|
case '0': case 'x': case 'r': lua_pushnumber(L, v[0]); break;
|
|
case '1': case 'y': case 'g': lua_pushnumber(L, v[1]); break;
|
|
case '2': case 'z': case 'b': lua_pushnumber(L, v[2]); break;
|
|
default: lua_pushnil(L); break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int Vector_NewIndex(lua_State *L) {
|
|
vec_t *v;
|
|
const char *i;
|
|
vec_t t;
|
|
|
|
v = Lua_GetVector(L, 1);
|
|
i = luaL_checkstring(L, 2);
|
|
t = luaL_checknumber(L, 3);
|
|
|
|
switch(*i) {
|
|
case '0': case 'x': case 'r': v[0] = t; break;
|
|
case '1': case 'y': case 'g': v[1] = t; break;
|
|
case '2': case 'z': case 'b': v[2] = t; break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Vector_AddOperator(lua_State *L) {
|
|
vec_t *a, *b;
|
|
vec3_t c;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
b = Lua_GetVector(L, 2);
|
|
|
|
VectorAdd(a, b, c);
|
|
|
|
Lua_PushVector(L, c);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Vector_SubOperator(lua_State *L) {
|
|
vec_t *a, *b;
|
|
vec3_t c;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
b = Lua_GetVector(L, 2);
|
|
|
|
VectorSubtract(a, b, c);
|
|
|
|
Lua_PushVector(L, c);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Vector_DotOperator(lua_State *L) {
|
|
vec_t *a, *b;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
b = Lua_GetVector(L, 2);
|
|
|
|
lua_pushnumber(L, DotProduct(a,b));
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Vector_NegateOperator(lua_State *L) {
|
|
vec_t *a;
|
|
vec3_t b;
|
|
|
|
a = Lua_GetVector(L, 1);
|
|
|
|
VectorNegate(a, b);
|
|
|
|
Lua_PushVector(L, b);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int Vector_GC(lua_State *L) {
|
|
return 0;
|
|
}
|
|
|
|
static int Vector_ToString(lua_State *L) {
|
|
vec_t *vec;
|
|
|
|
vec = Lua_GetVector(L,1);
|
|
lua_pushstring(L, va("(%i %i %i)", (int)vec[0], (int)vec[1], (int)vec[2]));
|
|
|
|
return 1;
|
|
}
|
|
|
|
static const luaL_Reg vector_ctor[] = {
|
|
{ "New", Vector_New },
|
|
{ "Construct", Vector_Construct },
|
|
{ "RotatePointAround", Vector_RotatePointAround },
|
|
{ "Perpendicular", Vector_Perpendicular },
|
|
{ "VecToAngles", Vector_VecToAngles },
|
|
{ "AngleVectors", Vector_AngleVectors },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const luaL_Reg vector_meta[] = {
|
|
{ "__index", Vector_Index },
|
|
{ "__newindex", Vector_NewIndex },
|
|
{ "__add", Vector_AddOperator },
|
|
{ "__sub", Vector_SubOperator },
|
|
{ "__mul", Vector_DotOperator },
|
|
{ "__unm", Vector_NegateOperator },
|
|
{ "__gc", Vector_GC },
|
|
{ "__tostring", Vector_ToString },
|
|
{ "Set", Vector_Set },
|
|
{ "Length", Vector_Length },
|
|
{ "Normalize", Vector_Normalize },
|
|
{ "NormalizeFast", Vector_NormalizeFast },
|
|
{ "Add", Vector_Add },
|
|
{ "Subtract", Vector_Subtract },
|
|
{ "Scale", Vector_Scale },
|
|
{ "Clear", Vector_Clear },
|
|
{NULL, NULL }
|
|
};
|
|
|
|
int Luaopen_Vector(lua_State *L) {
|
|
luaL_newmetatable(L, "vector");
|
|
|
|
luaL_register(L, NULL, vector_meta);
|
|
luaL_register(L, "vector", vector_ctor);
|
|
|
|
return 1;
|
|
}
|
|
|
|
void Lua_PushVector(lua_State *L, vec3_t v) {
|
|
vec_t *vec;
|
|
|
|
vec = (vec_t *)lua_newuserdata(L, sizeof(vec3_t));
|
|
|
|
luaL_getmetatable(L, "vector");
|
|
lua_setmetatable(L, -2);
|
|
|
|
VectorCopy(v, vec);
|
|
}
|
|
|
|
vec_t *Lua_GetVector(lua_State * L, int argNum)
|
|
{
|
|
void *ud;
|
|
|
|
ud = luaL_checkudata(L, argNum, "vector");
|
|
luaL_argcheck(L, ud != NULL, argNum, "`vector' expected");
|
|
return (vec_t *) ud;
|
|
}
|
|
|
|
int Lua_IsVector(lua_State * L, int idx)
|
|
{
|
|
void *ud;
|
|
|
|
if(lua_isuserdata(L, idx))
|
|
{
|
|
if(lua_getmetatable(L, idx))
|
|
{
|
|
ud = luaL_checkudata(L, idx, "vector");
|
|
return (ud != NULL);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|