Implement vectors, matrices and quaternions
This commit is contained in:
parent
8b2626165b
commit
18d54fc07b
14 changed files with 982 additions and 68 deletions
|
|
@ -26,6 +26,7 @@ hu_stuff.c
|
|||
i_time.c
|
||||
y_inter.c
|
||||
st_stuff.c
|
||||
matrix.c
|
||||
m_aatree.c
|
||||
m_anigif.c
|
||||
m_argv.c
|
||||
|
|
@ -65,6 +66,7 @@ p_slopes.c
|
|||
p_sweep.cpp
|
||||
p_test.cpp
|
||||
p_deepcopy.cpp
|
||||
quaternion.c
|
||||
tables.c
|
||||
r_bsp.cpp
|
||||
r_data.c
|
||||
|
|
@ -88,6 +90,7 @@ r_debug.cpp
|
|||
r_debug_parser.cpp
|
||||
screen.c
|
||||
taglist.c
|
||||
vector3d.c
|
||||
v_video.c
|
||||
s_sound.c
|
||||
sounds.c
|
||||
|
|
@ -117,6 +120,9 @@ lua_hudlib_drawlist.c
|
|||
lua_followerlib.c
|
||||
lua_terrainlib.c
|
||||
lua_waypointslib.c
|
||||
lua_vectorlib.c
|
||||
lua_matrixlib.c
|
||||
lua_quaternionlib.c
|
||||
k_kart.c
|
||||
k_collide.c
|
||||
k_color.c
|
||||
|
|
|
|||
|
|
@ -191,8 +191,6 @@ static const struct {
|
|||
{META_NODE, "node_t"},
|
||||
#endif
|
||||
{META_SLOPE, "slope_t"},
|
||||
{META_VECTOR2, "vector2_t"},
|
||||
{META_VECTOR3, "vector3_t"},
|
||||
{META_MAPHEADER, "mapheader_t"},
|
||||
|
||||
{META_POLYOBJ, "polyobj_t"},
|
||||
|
|
@ -245,6 +243,11 @@ static const struct {
|
|||
{META_OVERLAY, "t_overlay_t"},
|
||||
{META_TERRAIN, "terrain_t"},
|
||||
|
||||
{META_VECTOR2, "vector2_t"},
|
||||
{META_VECTOR3, "vector3_t"},
|
||||
{META_MATRIX, "matrix_t"},
|
||||
{META_QUATERNION, "quaternion_t"},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -65,8 +65,6 @@ extern lua_State *gL;
|
|||
#define META_NODE "NODE_T*"
|
||||
#endif
|
||||
#define META_SLOPE "PSLOPE_T*"
|
||||
#define META_VECTOR2 "VECTOR2_T"
|
||||
#define META_VECTOR3 "VECTOR3_T"
|
||||
#define META_MAPHEADER "MAPHEADER_T*"
|
||||
|
||||
#define META_POLYOBJ "POLYOBJ_T*"
|
||||
|
|
@ -119,6 +117,11 @@ extern lua_State *gL;
|
|||
#define META_OVERLAY "T_OVERLAY_T*"
|
||||
#define META_TERRAIN "TERRAIN_T*"
|
||||
|
||||
#define META_VECTOR2 "VECTOR2_T"
|
||||
#define META_VECTOR3 "VECTOR3_T"
|
||||
#define META_MATRIX "MATRIX_T"
|
||||
#define META_QUATERNION "QUATERNION_T"
|
||||
|
||||
boolean luaL_checkboolean(lua_State *L, int narg);
|
||||
|
||||
int LUA_EnumLib(lua_State *L);
|
||||
|
|
@ -141,6 +144,9 @@ int LUA_FollowerLib(lua_State *L);
|
|||
int LUA_BotVarsLib(lua_State *L);
|
||||
int LUA_TerrainLib(lua_State *L);
|
||||
int LUA_WaypointLib(lua_State *L);
|
||||
int LUA_MatrixLib(lua_State *L);
|
||||
int LUA_QuaternionLib(lua_State *L);
|
||||
int LUA_VectorLib(lua_State *L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -381,19 +381,6 @@ static const char *const slope_opt[] = {
|
|||
"flags",
|
||||
NULL};
|
||||
|
||||
// shared by both vector2_t and vector3_t
|
||||
enum vector_e {
|
||||
vector_x = 0,
|
||||
vector_y,
|
||||
vector_z
|
||||
};
|
||||
|
||||
static const char *const vector_opt[] = {
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
NULL};
|
||||
|
||||
enum activator_e {
|
||||
activator_valid = 0,
|
||||
activator_mo,
|
||||
|
|
@ -2486,47 +2473,6 @@ static int slope_set(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
///////////////
|
||||
// vector*_t //
|
||||
///////////////
|
||||
|
||||
static int vector2_get(lua_State *L)
|
||||
{
|
||||
vector2_t *vec = *((vector2_t **)luaL_checkudata(L, 1, META_VECTOR2));
|
||||
enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt);
|
||||
|
||||
if (!vec)
|
||||
return luaL_error(L, "accessed vector2_t doesn't exist anymore.");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case vector_x: lua_pushfixed(L, vec->x); return 1;
|
||||
case vector_y: lua_pushfixed(L, vec->y); return 1;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vector3_get(lua_State *L)
|
||||
{
|
||||
vector3_t *vec = *((vector3_t **)luaL_checkudata(L, 1, META_VECTOR3));
|
||||
enum vector_e field = luaL_checkoption(L, 2, vector_opt[0], vector_opt);
|
||||
|
||||
if (!vec)
|
||||
return luaL_error(L, "accessed vector3_t doesn't exist anymore.");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case vector_x: lua_pushfixed(L, vec->x); return 1;
|
||||
case vector_y: lua_pushfixed(L, vec->y); return 1;
|
||||
case vector_z: lua_pushfixed(L, vec->z); return 1;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// mapheaderinfo[] //
|
||||
/////////////////////
|
||||
|
|
@ -2896,16 +2842,6 @@ int LUA_MapLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_VECTOR2);
|
||||
lua_pushcfunction(L, vector2_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_VECTOR3);
|
||||
lua_pushcfunction(L, vector3_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_MAPHEADER);
|
||||
lua_pushcfunction(L, mapheaderinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
|
|
|||
205
src/lua_matrixlib.c
Normal file
205
src/lua_matrixlib.c
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by LJ Sonic
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file lua_matrixlib.c
|
||||
/// \brief matrix library for Lua scripting
|
||||
|
||||
#include "matrix.h"
|
||||
#include "vector3d.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
static vector3_t *GetVector(lua_State *L, int index)
|
||||
{
|
||||
vector3_t *vec = lua_touserdata(L, index);
|
||||
|
||||
if (!vec)
|
||||
return NULL;
|
||||
|
||||
if (!lua_getmetatable(L, index))
|
||||
return NULL;
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, META_VECTOR3);
|
||||
if (!lua_rawequal(L, -1, -2))
|
||||
return NULL;
|
||||
|
||||
lua_pop(L, 2);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
static matrix_t *NewMatrix(lua_State *L)
|
||||
{
|
||||
matrix_t *mat = lua_newuserdata(L, sizeof(*mat));
|
||||
luaL_getmetatable(L, META_MATRIX);
|
||||
lua_setmetatable(L, -2);
|
||||
return mat;
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// STATIC MEMBERS //
|
||||
////////////////////
|
||||
|
||||
static int matrix_new(lua_State *L)
|
||||
{
|
||||
Matrix_SetIdentity(NewMatrix(L));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int matrix_fromTranslation(lua_State *L)
|
||||
{
|
||||
fixed_t x = luaL_checkfixed(L, 1);
|
||||
fixed_t y = luaL_checkfixed(L, 2);
|
||||
fixed_t z = luaL_checkfixed(L, 3);
|
||||
|
||||
Matrix_SetTranslation(NewMatrix(L), x, y, z);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int matrix_fromScaling(lua_State *L)
|
||||
{
|
||||
fixed_t x = luaL_checkfixed(L, 1);
|
||||
fixed_t y = luaL_checkfixed(L, 2);
|
||||
fixed_t z = luaL_checkfixed(L, 3);
|
||||
|
||||
Matrix_SetScaling(NewMatrix(L), x, y, z);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static luaL_Reg matrix[] = {
|
||||
{"new", matrix_new},
|
||||
{"fromTranslation", matrix_fromTranslation},
|
||||
{"fromScaling", matrix_fromScaling},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/////////////
|
||||
// MEMBERS //
|
||||
/////////////
|
||||
|
||||
enum matrixfield_e {
|
||||
matrixfield_clone = 0,
|
||||
matrixfield_getvalue,
|
||||
matrixfield_setvalue,
|
||||
matrixfield_mulXYZ,
|
||||
};
|
||||
|
||||
static const char *const matrixfield_opt[] = {
|
||||
"clone",
|
||||
"mulXYZ",
|
||||
NULL};
|
||||
|
||||
static int matrix_clone(lua_State *L)
|
||||
{
|
||||
matrix_t *mat = luaL_checkudata(L, 1, META_MATRIX);
|
||||
Matrix_Copy(NewMatrix(L), mat);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int matrix_getvalue(lua_State *L)
|
||||
{
|
||||
matrix_t *mat = luaL_checkudata(L, 1, META_MATRIX);
|
||||
INT32 row = luaL_checkinteger(L, 2);
|
||||
INT32 col = luaL_checkinteger(L, 3);
|
||||
|
||||
if (row < 1 || row > 4)
|
||||
return luaL_error(L, "matrix row %d out of range (1 - 4)", row);
|
||||
if (col < 1 || col > 4)
|
||||
return luaL_error(L, "matrix column %d out of range (1 - 4)", col);
|
||||
|
||||
lua_pushfixed(L, mat->matrix[row - 1][col - 1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int matrix_setvalue(lua_State *L)
|
||||
{
|
||||
matrix_t *mat = luaL_checkudata(L, 1, META_MATRIX);
|
||||
INT32 row = luaL_checkinteger(L, 2);
|
||||
INT32 col = luaL_checkinteger(L, 3);
|
||||
fixed_t value = luaL_checkfixed(L, 4);
|
||||
|
||||
if (row < 1 || row > 4)
|
||||
return luaL_error(L, "matrix row %d out of range (1 - 4)", row);
|
||||
if (col < 1 || col > 4)
|
||||
return luaL_error(L, "matrix column %d out of range (1 - 4)", col);
|
||||
|
||||
mat->matrix[row - 1][col - 1] = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int matrix_mulXYZ(lua_State *L)
|
||||
{
|
||||
matrix_t *mat = luaL_checkudata(L, 1, META_MATRIX);
|
||||
fixed_t x = luaL_checkfixed(L, 2);
|
||||
fixed_t y = luaL_checkfixed(L, 3);
|
||||
fixed_t z = luaL_checkfixed(L, 4);
|
||||
|
||||
vector3_t vec;
|
||||
vector3_t result;
|
||||
Vector3D_Set(&vec, x, y, z);
|
||||
Matrix_MulVector(&result, mat, &vec);
|
||||
|
||||
lua_pushfixed(L, result.x);
|
||||
lua_pushfixed(L, result.y);
|
||||
lua_pushfixed(L, result.z);
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int matrix_get(lua_State *L)
|
||||
{
|
||||
enum matrixfield_e field = luaL_checkoption(L, 2, matrixfield_opt[0], matrixfield_opt);
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case matrixfield_clone: lua_pushcfunction(L, matrix_clone); return 1;
|
||||
case matrixfield_getvalue: lua_pushcfunction(L, matrix_getvalue); return 1;
|
||||
case matrixfield_setvalue: lua_pushcfunction(L, matrix_setvalue); return 1;
|
||||
case matrixfield_mulXYZ: lua_pushcfunction(L, matrix_mulXYZ); return 1;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////
|
||||
// OPERATORS //
|
||||
///////////////
|
||||
|
||||
static int matrix_mul(lua_State *L)
|
||||
{
|
||||
matrix_t *mat1 = luaL_checkudata(L, 1, META_MATRIX);
|
||||
|
||||
vector3_t *vec2 = GetVector(L, 2);
|
||||
if (vec2)
|
||||
{
|
||||
vector3_t *result = lua_newuserdata(L, sizeof(*result));
|
||||
luaL_getmetatable(L, META_VECTOR3);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
Matrix_MulVector(result, mat1, vec2);
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix_t *mat2 = luaL_checkudata(L, 2, META_MATRIX);
|
||||
Matrix_Mul(NewMatrix(L), mat1, mat2);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LUA_MatrixLib(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, META_MATRIX);
|
||||
LUA_SetCFunctionField(L, "__index", matrix_get);
|
||||
LUA_SetCFunctionField(L, "__mul", matrix_mul);
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_register(L, "Matrix", matrix);
|
||||
return 0;
|
||||
}
|
||||
131
src/lua_quaternionlib.c
Normal file
131
src/lua_quaternionlib.c
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by LJ Sonic
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file lua_quaternionlib.c
|
||||
/// \brief quaternion library for Lua scripting
|
||||
|
||||
#include "quaternion.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
static quaternion_t *NewQuaternion(lua_State *L)
|
||||
{
|
||||
quaternion_t *quat = lua_newuserdata(L, sizeof(*quat));
|
||||
luaL_getmetatable(L, META_QUATERNION);
|
||||
lua_setmetatable(L, -2);
|
||||
return quat;
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// STATIC MEMBERS //
|
||||
////////////////////
|
||||
|
||||
static int quaternion_new(lua_State *L)
|
||||
{
|
||||
Quaternion_SetIdentity(NewQuaternion(L));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quaternion_fromAxisRotation(lua_State *L)
|
||||
{
|
||||
vector3_t *axis = luaL_checkudata(L, 1, META_VECTOR3);
|
||||
fixed_t angle = luaL_checkfixed(L, 2);
|
||||
Quaternion_SetAxisRotation(NewQuaternion(L), axis, angle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static luaL_Reg quaternion[] = {
|
||||
{"new", quaternion_new},
|
||||
{"fromAxisRotation", quaternion_fromAxisRotation},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/////////////
|
||||
// MEMBERS //
|
||||
/////////////
|
||||
|
||||
static int quaternion_clone(lua_State *L)
|
||||
{
|
||||
quaternion_t *quat = luaL_checkudata(L, 1, META_QUATERNION);
|
||||
Quaternion_Copy(NewQuaternion(L), quat);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int quaternion_toMatrix(lua_State *L)
|
||||
{
|
||||
quaternion_t *quat = luaL_checkudata(L, 1, META_QUATERNION);
|
||||
|
||||
matrix_t *mat = lua_newuserdata(L, sizeof(*mat));
|
||||
luaL_getmetatable(L, META_MATRIX);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
Quaternion_ToMatrix(mat, quat);
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum quaternionfield_e {
|
||||
quaternionfield_clone = 0,
|
||||
quaternionfield_toMatrix,
|
||||
quaternionfield_x,
|
||||
quaternionfield_y,
|
||||
quaternionfield_z,
|
||||
quaternionfield_w,
|
||||
};
|
||||
|
||||
static const char *const quaternionfield_opt[] = {
|
||||
"clone",
|
||||
"toMatrix",
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"w",
|
||||
NULL};
|
||||
|
||||
static int quaternion_get(lua_State *L)
|
||||
{
|
||||
quaternion_t *quat = luaL_checkudata(L, 1, META_QUATERNION);
|
||||
enum quaternionfield_e field = luaL_checkoption(L, 2, quaternionfield_opt[0], quaternionfield_opt);
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case quaternionfield_clone: lua_pushcfunction(L, quaternion_clone); return 1;
|
||||
case quaternionfield_toMatrix: lua_pushcfunction(L, quaternion_toMatrix); return 1;
|
||||
|
||||
case quaternionfield_x: lua_pushfixed(L, quat->x); return 1;
|
||||
case quaternionfield_y: lua_pushfixed(L, quat->y); return 1;
|
||||
case quaternionfield_z: lua_pushfixed(L, quat->z); return 1;
|
||||
case quaternionfield_w: lua_pushfixed(L, quat->w); return 1;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////
|
||||
// OPERATORS //
|
||||
///////////////
|
||||
|
||||
static int quaternion_mul(lua_State *L)
|
||||
{
|
||||
quaternion_t *quat1 = luaL_checkudata(L, 1, META_QUATERNION);
|
||||
quaternion_t *quat2 = luaL_checkudata(L, 2, META_QUATERNION);
|
||||
Quaternion_Mul(NewQuaternion(L), quat1, quat2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LUA_QuaternionLib(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, META_QUATERNION);
|
||||
LUA_SetCFunctionField(L, "__index", quaternion_get);
|
||||
LUA_SetCFunctionField(L, "__mul", quaternion_mul);
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_register(L, "Quaternion", quaternion);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -63,6 +63,9 @@ static lua_CFunction liblist[] = {
|
|||
LUA_BotVarsLib, // botvars_t
|
||||
LUA_TerrainLib, // t_splash_t, t_footstep_t, t_overlay_t, terrain_t
|
||||
LUA_WaypointLib, // waypoint_t
|
||||
LUA_VectorLib, // vectors
|
||||
LUA_MatrixLib, // matrices
|
||||
LUA_QuaternionLib, // quaternions
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
|||
217
src/lua_vectorlib.c
Normal file
217
src/lua_vectorlib.c
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by LJ Sonic
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file lua_vectorlib.c
|
||||
/// \brief vector library for Lua scripting
|
||||
|
||||
#include "vector3d.h"
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
// shared by both Vector2D and Vector3D
|
||||
enum vectorfield_e {
|
||||
vectorfield_clone = 0,
|
||||
vectorfield_opposite,
|
||||
vectorfield_x,
|
||||
vectorfield_y,
|
||||
vectorfield_z,
|
||||
vectorfield_length,
|
||||
vectorfield_normalized,
|
||||
};
|
||||
|
||||
static const char *const vectorfield_opt[] = {
|
||||
"vector_clone",
|
||||
"vector_opposite",
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"vector_length",
|
||||
"vector_normalized",
|
||||
NULL};
|
||||
|
||||
////////////////////////////
|
||||
// VECTOR2 STATIC MEMBERS //
|
||||
////////////////////////////
|
||||
|
||||
/////////////////////
|
||||
// VECTOR2 MEMBERS //
|
||||
/////////////////////
|
||||
|
||||
static int vector2d_get(lua_State *L)
|
||||
{
|
||||
vector2_t *vec = *((vector2_t **)luaL_checkudata(L, 1, META_VECTOR2));
|
||||
enum vectorfield_e field = luaL_checkoption(L, 2, vectorfield_opt[0], vectorfield_opt);
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case vectorfield_x: lua_pushfixed(L, vec->x); return 1;
|
||||
case vectorfield_y: lua_pushfixed(L, vec->y); return 1;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////
|
||||
// VECTOR3 //
|
||||
/////////////
|
||||
|
||||
static vector3_t *NewVector3(lua_State *L)
|
||||
{
|
||||
vector3_t *vec = lua_newuserdata(L, sizeof(*vec));
|
||||
luaL_getmetatable(L, META_VECTOR3);
|
||||
lua_setmetatable(L, -2);
|
||||
return vec;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// VECTOR3 STATIC MEMBERS //
|
||||
////////////////////////////
|
||||
|
||||
static int vector3d_new(lua_State *L)
|
||||
{
|
||||
fixed_t x = luaL_checkfixed(L, 1);
|
||||
fixed_t y = luaL_checkfixed(L, 2);
|
||||
fixed_t z = luaL_optfixed(L, 3, 0);
|
||||
|
||||
Vector3D_Set(NewVector3(L), x, y, z);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static luaL_Reg vector3d[] = {
|
||||
{"new", vector3d_new},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/////////////////////
|
||||
// VECTOR3 MEMBERS //
|
||||
/////////////////////
|
||||
|
||||
static int vector3d_clone(lua_State *L)
|
||||
{
|
||||
vector3_t *vec = luaL_checkudata(L, 1, META_VECTOR3);
|
||||
Vector3D_Copy(NewVector3(L), vec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vector3d_opposite(lua_State *L)
|
||||
{
|
||||
vector3_t *vec = luaL_checkudata(L, 1, META_VECTOR3);
|
||||
Vector3D_Opposite(NewVector3(L), vec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vector3d_get(lua_State *L)
|
||||
{
|
||||
vector3_t *vec = luaL_checkudata(L, 1, META_VECTOR3);
|
||||
enum vectorfield_e field = luaL_checkoption(L, 2, vectorfield_opt[0], vectorfield_opt);
|
||||
|
||||
if (!vec)
|
||||
return luaL_error(L, "accessed vector3_t doesn't exist anymore.");
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case vectorfield_clone: lua_pushcfunction(L, vector3d_clone); return 1;
|
||||
case vectorfield_opposite: lua_pushcfunction(L, vector3d_opposite); return 1;
|
||||
|
||||
case vectorfield_x: lua_pushfixed(L, vec->x); return 1;
|
||||
case vectorfield_y: lua_pushfixed(L, vec->y); return 1;
|
||||
case vectorfield_z: lua_pushfixed(L, vec->z); return 1;
|
||||
case vectorfield_length: lua_pushfixed(L, Vector3D_Length(vec)); return 1;
|
||||
case vectorfield_normalized: Vector3D_Normalize(NewVector3(L), vec); return 1;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
// VECTOR3 OPERATORS //
|
||||
///////////////////////
|
||||
|
||||
static int vector3d_eq(lua_State *L)
|
||||
{
|
||||
vector3_t *vec1 = luaL_checkudata(L, 1, META_VECTOR3);
|
||||
vector3_t *vec2 = luaL_checkudata(L, 2, META_VECTOR3);
|
||||
lua_pushboolean(L, Vector3D_Equal(vec1, vec2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vector3d_op(
|
||||
lua_State *L,
|
||||
vector3_t *(*opvector)(vector3_t*, vector3_t*, vector3_t*),
|
||||
vector3_t *(*opfixed)(vector3_t*, vector3_t*, fixed_t)
|
||||
)
|
||||
{
|
||||
if (lua_isnumber(L, 1) && (opfixed == Vector3D_AddFixed || opfixed == Vector3D_MulFixed))
|
||||
{
|
||||
fixed_t n1 = lua_tofixed(L, 1);
|
||||
vector3_t *vec2 = luaL_checkudata(L, 2, META_VECTOR3);
|
||||
opfixed(NewVector3(L), vec2, n1);
|
||||
}
|
||||
else if (lua_isnumber(L, 2))
|
||||
{
|
||||
vector3_t *vec1 = luaL_checkudata(L, 1, META_VECTOR3);
|
||||
fixed_t n2 = lua_tofixed(L, 2);
|
||||
opfixed(NewVector3(L), vec1, n2);
|
||||
}
|
||||
else
|
||||
{
|
||||
vector3_t *vec1 = luaL_checkudata(L, 1, META_VECTOR3);
|
||||
vector3_t *vec2 = luaL_checkudata(L, 2, META_VECTOR3);
|
||||
opvector(NewVector3(L), vec1, vec2);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vector3d_add(lua_State *L)
|
||||
{
|
||||
return vector3d_op(L, Vector3D_Add, Vector3D_AddFixed);
|
||||
}
|
||||
|
||||
static int vector3d_sub(lua_State *L)
|
||||
{
|
||||
return vector3d_op(L, Vector3D_Sub, Vector3D_SubFixed);
|
||||
}
|
||||
|
||||
static int vector3d_mul(lua_State *L)
|
||||
{
|
||||
return vector3d_op(L, Vector3D_Mul, Vector3D_MulFixed);
|
||||
}
|
||||
|
||||
static int vector3d_div(lua_State *L)
|
||||
{
|
||||
return vector3d_op(L, Vector3D_Div, Vector3D_DivFixed);
|
||||
}
|
||||
|
||||
static int vector3d_unm(lua_State *L)
|
||||
{
|
||||
vector3_t *vec = luaL_checkudata(L, 1, META_VECTOR3);
|
||||
Vector3D_Opposite(NewVector3(L), vec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LUA_VectorLib(lua_State *L)
|
||||
{
|
||||
LUA_RegisterUserdataMetatable(L, META_VECTOR2, vector2d_get, NULL, NULL);
|
||||
|
||||
luaL_newmetatable(L, META_VECTOR3);
|
||||
LUA_SetCFunctionField(L, "__index", vector3d_get);
|
||||
LUA_SetCFunctionField(L, "__eq", vector3d_eq);
|
||||
LUA_SetCFunctionField(L, "__add", vector3d_add);
|
||||
LUA_SetCFunctionField(L, "__sub", vector3d_sub);
|
||||
LUA_SetCFunctionField(L, "__mul", vector3d_mul);
|
||||
LUA_SetCFunctionField(L, "__div", vector3d_div);
|
||||
LUA_SetCFunctionField(L, "__unm", vector3d_unm);
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_register(L, "Vector3D", vector3d);
|
||||
return 0;
|
||||
}
|
||||
70
src/matrix.c
Normal file
70
src/matrix.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by LJ Sonic
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file matrix.c
|
||||
/// \brief Fixed-point 3D vector
|
||||
|
||||
#include "matrix.h"
|
||||
|
||||
static matrix_t identitymatrix = {{
|
||||
{FRACUNIT, 0, 0, 0},
|
||||
{0, FRACUNIT, 0, 0},
|
||||
{0, 0, FRACUNIT, 0},
|
||||
{0, 0, 0, FRACUNIT},
|
||||
}};
|
||||
|
||||
matrix_t *Matrix_SetIdentity(matrix_t *mat)
|
||||
{
|
||||
return memcpy(mat, identitymatrix.matrix, sizeof(*mat));
|
||||
}
|
||||
|
||||
matrix_t *Matrix_SetTranslation(matrix_t *mat, fixed_t x, fixed_t y, fixed_t z)
|
||||
{
|
||||
Matrix_SetIdentity(mat);
|
||||
|
||||
mat->matrix[0][3] = x;
|
||||
mat->matrix[1][3] = y;
|
||||
mat->matrix[2][3] = z;
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
matrix_t *Matrix_SetScaling(matrix_t *mat, fixed_t x, fixed_t y, fixed_t z)
|
||||
{
|
||||
Matrix_SetIdentity(mat);
|
||||
|
||||
mat->matrix[0][0] = x;
|
||||
mat->matrix[1][1] = y;
|
||||
mat->matrix[2][2] = z;
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
matrix_t *Matrix_Copy(matrix_t *out, matrix_t *in)
|
||||
{
|
||||
return memcpy(out, in, sizeof(*out));
|
||||
}
|
||||
|
||||
matrix_t *Matrix_Mul(matrix_t *out, matrix_t *a, matrix_t *b)
|
||||
{
|
||||
for (size_t r = 0; r < 4; r++)
|
||||
for (size_t c = 0; c < 4; c++)
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
out->matrix[r][c] += FixedMul(a->matrix[r][i], b->matrix[i][c]);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
vector3_t *Matrix_MulVector(vector3_t *out, matrix_t *a, vector3_t *b)
|
||||
{
|
||||
out->x = FixedMul(a->matrix[0][0], b->x) + FixedMul(a->matrix[0][1], b->y) + FixedMul(a->matrix[0][2], b->z) + a->matrix[0][3];
|
||||
out->y = FixedMul(a->matrix[1][0], b->x) + FixedMul(a->matrix[1][1], b->y) + FixedMul(a->matrix[1][2], b->z) + a->matrix[1][3];
|
||||
out->z = FixedMul(a->matrix[2][0], b->x) + FixedMul(a->matrix[2][1], b->y) + FixedMul(a->matrix[2][2], b->z) + a->matrix[2][3];
|
||||
|
||||
return out;
|
||||
}
|
||||
30
src/matrix.h
Normal file
30
src/matrix.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by LJ Sonic
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file matrix.c
|
||||
/// \brief Fixed-point 4x4 matrix
|
||||
|
||||
#ifndef __MATRIX__
|
||||
#define __MATRIX__
|
||||
|
||||
#include "m_fixed.h"
|
||||
#include "vector3d.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t matrix[4][4];
|
||||
} matrix_t;
|
||||
|
||||
matrix_t *Matrix_SetIdentity(matrix_t *mat);
|
||||
matrix_t *Matrix_SetTranslation(matrix_t *mat, fixed_t x, fixed_t y, fixed_t z);
|
||||
matrix_t *Matrix_SetScaling(matrix_t *mat, fixed_t x, fixed_t y, fixed_t z);
|
||||
matrix_t *Matrix_Copy(matrix_t *out, matrix_t *in);
|
||||
matrix_t *Matrix_Mul(matrix_t *out, matrix_t *a, matrix_t *b);
|
||||
vector3_t *Matrix_MulVector(vector3_t *out, matrix_t *a, vector3_t *b);
|
||||
|
||||
#endif
|
||||
118
src/quaternion.c
Normal file
118
src/quaternion.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by LJ Sonic
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file quaternion.c
|
||||
/// \brief Fixed-point 3D vector
|
||||
|
||||
#include "quaternion.h"
|
||||
#include "vector3d.h"
|
||||
#include "matrix.h"
|
||||
#include "r_main.h" // R_PointToDist2
|
||||
|
||||
quaternion_t *Quaternion_Set(quaternion_t *quat, fixed_t x, fixed_t y, fixed_t z, fixed_t w)
|
||||
{
|
||||
quat->x = x;
|
||||
quat->y = y;
|
||||
quat->z = z;
|
||||
quat->w = w;
|
||||
|
||||
return quat;
|
||||
}
|
||||
|
||||
quaternion_t *Quaternion_SetIdentity(quaternion_t *quat)
|
||||
{
|
||||
return Quaternion_Set(quat, 0, 0, 0, FRACUNIT);
|
||||
}
|
||||
|
||||
quaternion_t *Quaternion_SetAxisRotation(quaternion_t *quat, vector3_t *axis, fixed_t angle)
|
||||
{
|
||||
fixed_t cosangle = FINECOSINE(((angle / 2) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
fixed_t sinangle = FINESINE(((angle / 2) >> ANGLETOFINESHIFT) & FINEMASK);
|
||||
vector3_t normaxis;
|
||||
|
||||
Vector3D_Normalize(&normaxis, axis);
|
||||
|
||||
return Quaternion_Set(quat,
|
||||
FixedMul(normaxis.x, sinangle),
|
||||
FixedMul(normaxis.y, sinangle),
|
||||
FixedMul(normaxis.z, sinangle),
|
||||
cosangle
|
||||
);
|
||||
}
|
||||
|
||||
quaternion_t *Quaternion_Copy(quaternion_t *out, quaternion_t *in)
|
||||
{
|
||||
return memcpy(out, in, sizeof(*out));
|
||||
}
|
||||
|
||||
matrix_t *Quaternion_ToMatrix(matrix_t *mat, const quaternion_t *quat)
|
||||
{
|
||||
fixed_t x = quat->x, y = quat->y, z = quat->z, w = quat->w;
|
||||
|
||||
fixed_t xx2 = 2 * FixedMul(x, x);
|
||||
fixed_t xy2 = 2 * FixedMul(x, y);
|
||||
fixed_t xz2 = 2 * FixedMul(x, z);
|
||||
fixed_t xw2 = 2 * FixedMul(x, w);
|
||||
fixed_t yy2 = 2 * FixedMul(y, y);
|
||||
fixed_t yz2 = 2 * FixedMul(y, z);
|
||||
fixed_t yw2 = 2 * FixedMul(y, w);
|
||||
fixed_t zz2 = 2 * FixedMul(z, z);
|
||||
fixed_t zw2 = 2 * FixedMul(z, w);
|
||||
|
||||
Matrix_SetIdentity(mat);
|
||||
|
||||
mat->matrix[0][0] = FRACUNIT - yy2 - zz2;
|
||||
mat->matrix[0][1] = xy2 - zw2;
|
||||
mat->matrix[0][2] = xz2 + yw2;
|
||||
|
||||
mat->matrix[1][0] = xy2 + zw2;
|
||||
mat->matrix[1][1] = FRACUNIT - xx2 - zz2;
|
||||
mat->matrix[1][2] = yz2 - xw2;
|
||||
|
||||
mat->matrix[2][0] = xz2 - yw2;
|
||||
mat->matrix[2][1] = yz2 + xw2;
|
||||
mat->matrix[2][2] = FRACUNIT - xx2 - yy2;
|
||||
|
||||
mat->matrix[3][3] = FRACUNIT;
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
quaternion_t *Quaternion_Normalize(quaternion_t *out, quaternion_t *in)
|
||||
{
|
||||
fixed_t sqlen =
|
||||
FixedMul(in->x, in->x) +
|
||||
FixedMul(in->y, in->y) +
|
||||
FixedMul(in->z, in->z) +
|
||||
FixedMul(in->w, in->w);
|
||||
|
||||
if (sqlen < FRACUNIT / 1024)
|
||||
return Quaternion_Set(out, in->x, in->y, in->z, in->w);
|
||||
|
||||
fixed_t len = R_PointToDist2(0, 0, R_PointToDist2(0, 0, R_PointToDist2(0, 0, in->x, in->y), in->z), in->w);
|
||||
|
||||
return Quaternion_Set(out,
|
||||
FixedDiv(in->x, len),
|
||||
FixedDiv(in->y, len),
|
||||
FixedDiv(in->z, len),
|
||||
FixedDiv(in->w, len)
|
||||
);
|
||||
}
|
||||
|
||||
quaternion_t *Quaternion_Mul(quaternion_t *out, quaternion_t *a, quaternion_t *b)
|
||||
{
|
||||
fixed_t ax = a->x, ay = a->y, az = a->z, aw = a->w;
|
||||
fixed_t bx = b->x, by = b->y, bz = b->z, bw = b->w;
|
||||
|
||||
return Quaternion_Normalize(out, Quaternion_Set(out,
|
||||
FixedMul(aw, bx) + FixedMul(ax, bw) + FixedMul(ay, bz) - FixedMul(az, by),
|
||||
FixedMul(aw, by) - FixedMul(ax, bz) + FixedMul(ay, bw) + FixedMul(az, bx),
|
||||
FixedMul(aw, bz) + FixedMul(ax, by) - FixedMul(ay, bx) + FixedMul(az, bw),
|
||||
FixedMul(aw, bw) - FixedMul(ax, bx) - FixedMul(ay, by) - FixedMul(az, bz)
|
||||
));
|
||||
}
|
||||
31
src/quaternion.h
Normal file
31
src/quaternion.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by LJ Sonic
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file quaternion.c
|
||||
/// \brief Fixed-point quaternion
|
||||
|
||||
#ifndef __QUATERNION__
|
||||
#define __QUATERNION__
|
||||
|
||||
#include "m_fixed.h"
|
||||
#include "matrix.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t x, y, z, w;
|
||||
} quaternion_t;
|
||||
|
||||
quaternion_t *Quaternion_Set(quaternion_t *quat, fixed_t x, fixed_t y, fixed_t z, fixed_t w);
|
||||
quaternion_t *Quaternion_SetIdentity(quaternion_t *quat);
|
||||
quaternion_t *Quaternion_SetAxisRotation(quaternion_t *quat, vector3_t *axis, fixed_t angle);
|
||||
quaternion_t *Quaternion_Copy(quaternion_t *out, quaternion_t *in);
|
||||
matrix_t *Quaternion_ToMatrix(matrix_t *mat, const quaternion_t *quat);
|
||||
quaternion_t *Quaternion_Normalize(quaternion_t *out, quaternion_t *in);
|
||||
quaternion_t *Quaternion_Mul(quaternion_t *out, quaternion_t *a, quaternion_t *b);
|
||||
|
||||
#endif
|
||||
124
src/vector3d.c
Normal file
124
src/vector3d.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by LJ Sonic
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file vector3d.c
|
||||
/// \brief Fixed-point 3D vector
|
||||
|
||||
#include "vector3d.h"
|
||||
#include "r_main.h" // R_PointToDist2
|
||||
|
||||
vector3_t *Vector3D_Set(vector3_t *vec, fixed_t x, fixed_t y, fixed_t z)
|
||||
{
|
||||
vec->x = x;
|
||||
vec->y = y;
|
||||
vec->z = z;
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_Copy(vector3_t *out, vector3_t *in)
|
||||
{
|
||||
return memcpy(out, in, sizeof(*out));
|
||||
}
|
||||
|
||||
fixed_t Vector3D_Length(vector3_t *vec)
|
||||
{
|
||||
return R_PointToDist2(0, 0, R_PointToDist2(0, 0, vec->x, vec->y), vec->z);
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_Opposite(vector3_t *out, vector3_t *in)
|
||||
{
|
||||
return Vector3D_Set(out, -in->x, -in->y, -in->z);
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_Normalize(vector3_t *out, vector3_t *in)
|
||||
{
|
||||
fixed_t len = Vector3D_Length(in);
|
||||
|
||||
if (len == 0)
|
||||
return Vector3D_Set(out, in->x, in->y, in->z);
|
||||
else
|
||||
return Vector3D_Set(out, FixedDiv(in->x, len), FixedDiv(in->y, len), FixedDiv(in->z, len));
|
||||
}
|
||||
|
||||
boolean Vector3D_Equal(vector3_t *a, vector3_t *b)
|
||||
{
|
||||
return (a->x == b->x && a->y == b->y && a->z == b->z);
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_Add(vector3_t *out, vector3_t *a, vector3_t *b)
|
||||
{
|
||||
out->x = a->x + b->x;
|
||||
out->y = a->y + b->y;
|
||||
out->z = a->z + b->z;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_Sub(vector3_t *out, vector3_t *a, vector3_t *b)
|
||||
{
|
||||
out->x = a->x - b->x;
|
||||
out->y = a->y - b->y;
|
||||
out->z = a->z - b->z;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_Mul(vector3_t *out, vector3_t *a, vector3_t *b)
|
||||
{
|
||||
out->x = FixedMul(a->x, b->x);
|
||||
out->y = FixedMul(a->y, b->y);
|
||||
out->z = FixedMul(a->z, b->z);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_Div(vector3_t *out, vector3_t *a, vector3_t *b)
|
||||
{
|
||||
out->x = FixedDiv(a->x, b->x);
|
||||
out->y = FixedDiv(a->y, b->y);
|
||||
out->z = FixedDiv(a->z, b->z);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_AddFixed(vector3_t *out, vector3_t *a, fixed_t b)
|
||||
{
|
||||
out->x = a->x + b;
|
||||
out->y = a->y + b;
|
||||
out->z = a->z + b;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_SubFixed(vector3_t *out, vector3_t *a, fixed_t b)
|
||||
{
|
||||
out->x = a->x - b;
|
||||
out->y = a->y - b;
|
||||
out->z = a->z - b;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_MulFixed(vector3_t *out, vector3_t *a, fixed_t b)
|
||||
{
|
||||
out->x = FixedMul(a->x, b);
|
||||
out->y = FixedMul(a->y, b);
|
||||
out->z = FixedMul(a->z, b);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
vector3_t *Vector3D_DivFixed(vector3_t *out, vector3_t *a, fixed_t b)
|
||||
{
|
||||
out->x = FixedDiv(a->x, b);
|
||||
out->y = FixedDiv(a->y, b);
|
||||
out->z = FixedDiv(a->z, b);
|
||||
|
||||
return out;
|
||||
}
|
||||
34
src/vector3d.h
Normal file
34
src/vector3d.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2025 by LJ Sonic
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file vector3d.c
|
||||
/// \brief Fixed-point 3D vector
|
||||
|
||||
#ifndef __VECTOR3D__
|
||||
#define __VECTOR3D__
|
||||
|
||||
#include "m_fixed.h"
|
||||
|
||||
vector3_t *Vector3D_Set(vector3_t *vec, fixed_t x, fixed_t y, fixed_t z);
|
||||
vector3_t *Vector3D_Copy(vector3_t *out, vector3_t *in);
|
||||
fixed_t Vector3D_Length(vector3_t *vec);
|
||||
vector3_t *Vector3D_Opposite(vector3_t *out, vector3_t *in);
|
||||
vector3_t *Vector3D_Normalize(vector3_t *out, vector3_t *in);
|
||||
boolean Vector3D_Equal(vector3_t *a, vector3_t *b);
|
||||
|
||||
vector3_t *Vector3D_Add(vector3_t *out, vector3_t *a, vector3_t *b);
|
||||
vector3_t *Vector3D_Sub(vector3_t *out, vector3_t *a, vector3_t *b);
|
||||
vector3_t *Vector3D_Mul(vector3_t *out, vector3_t *a, vector3_t *b);
|
||||
vector3_t *Vector3D_Div(vector3_t *out, vector3_t *a, vector3_t *b);
|
||||
|
||||
vector3_t *Vector3D_AddFixed(vector3_t *out, vector3_t *a, fixed_t b);
|
||||
vector3_t *Vector3D_SubFixed(vector3_t *out, vector3_t *a, fixed_t b);
|
||||
vector3_t *Vector3D_MulFixed(vector3_t *out, vector3_t *a, fixed_t b);
|
||||
vector3_t *Vector3D_DivFixed(vector3_t *out, vector3_t *a, fixed_t b);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue