naev 0.12.5
nlua_transform.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
11
12#include "naev.h"
14
15#include "nlua_transform.h"
16
17#include "nluadef.h"
18
19/* Transform metatable methods. */
20static int transformL_tostring( lua_State *L );
21static int transformL_eq( lua_State *L );
22static int transformL_new( lua_State *L );
23static int transformL_mul( lua_State *L );
24static int transformL_get( lua_State *L );
25static int transformL_set( lua_State *L );
26static int transformL_scale( lua_State *L );
27static int transformL_translate( lua_State *L );
28static int transformL_rotate2d( lua_State *L );
29static int transformL_ortho( lua_State *L );
30static int transformL_applyPoint( lua_State *L );
31static int transformL_applyDim( lua_State *L );
32
33static const luaL_Reg transformL_methods[] = {
34 { "__tostring", transformL_tostring },
35 { "__eq", transformL_eq },
36 { "__mul", transformL_mul },
37 { "get", transformL_get },
38 { "set", transformL_set },
39 { "new", transformL_new },
40 { "scale", transformL_scale },
41 { "translate", transformL_translate },
42 { "rotate2d", transformL_rotate2d },
43 { "ortho", transformL_ortho },
44 { "applyPoint", transformL_applyPoint },
45 { "applyDim", transformL_applyDim },
46 { 0, 0 } };
47
54int nlua_loadTransform( nlua_env env )
55{
56 nlua_register( env, TRANSFORM_METATABLE, transformL_methods, 1 );
57 return 0;
58}
59
72mat4 *lua_totransform( lua_State *L, int ind )
73{
74 return (mat4 *)lua_touserdata( L, ind );
75}
76
84mat4 *luaL_checktransform( lua_State *L, int ind )
85{
86 if ( lua_istransform( L, ind ) )
87 return lua_totransform( L, ind );
88 luaL_typerror( L, ind, TRANSFORM_METATABLE );
89 return NULL;
90}
91
98mat4 *lua_pushtransform( lua_State *L, mat4 transform )
99{
100 mat4 *t = (mat4 *)lua_newuserdata( L, sizeof( mat4 ) );
101 *t = transform;
102 luaL_getmetatable( L, TRANSFORM_METATABLE );
103 lua_setmetatable( L, -2 );
104 return t;
105}
106
113int lua_istransform( lua_State *L, int ind )
114{
115 int ret;
116
117 if ( lua_getmetatable( L, ind ) == 0 )
118 return 0;
119 lua_getfield( L, LUA_REGISTRYINDEX, TRANSFORM_METATABLE );
120
121 ret = 0;
122 if ( lua_rawequal( L, -1, -2 ) ) /* does it have the correct mt? */
123 ret = 1;
124
125 lua_pop( L, 2 ); /* remove both metatables */
126 return ret;
127}
128
136static int transformL_tostring( lua_State *L )
137{
138 char buf[STRMAX_SHORT];
139 const mat4 *t = luaL_checktransform( L, 1 );
140 mat4_tostr( t, buf, sizeof( buf ) );
141 lua_pushstring( L, buf );
142 return 1;
143}
144
153static int transformL_eq( lua_State *L )
154{
155 const mat4 *t1 = luaL_checktransform( L, 1 );
156 const mat4 *t2 = luaL_checktransform( L, 2 );
157 lua_pushboolean( L, ( memcmp( t1, t2, sizeof( mat4 ) ) == 0 ) );
158 return 1;
159}
160
167static int transformL_new( lua_State *L )
168{
169 if ( lua_istransform( L, 1 ) ) {
170 const mat4 *M = lua_totransform( L, 1 );
171 lua_pushtransform( L, *M );
172 } else
174 return 1;
175}
176
185static int transformL_mul( lua_State *L )
186{
187 const mat4 *A = luaL_checktransform( L, 1 );
188 const mat4 *B = luaL_checktransform( L, 2 );
189 mat4 C;
190 mat4_mul( &C, A, B );
191 lua_pushtransform( L, C );
192 return 1;
193}
194
204static int transformL_get( lua_State *L )
205{
206 mat4 *M = luaL_checktransform( L, 1 );
207 lua_newtable( L ); /* t */
208 for ( int i = 0; i < 4; i++ ) {
209 lua_newtable( L ); /* t, t */
210 for ( int j = 0; j < 4; j++ ) {
211 lua_pushnumber( L, M->m[j][i] ); /* t, t, n */
212 lua_rawseti( L, -2, j + 1 ); /* t, t */
213 }
214 lua_rawseti( L, -2, i + 1 ); /* t */
215 }
216 return 1;
217}
218
228static int transformL_set( lua_State *L )
229{
230 mat4 *M = luaL_checktransform( L, 1 );
231 int i = luaL_checkinteger( L, 2 ) - 1;
232 int j = luaL_checkinteger( L, 3 ) - 1;
233 double v = luaL_checknumber( L, 4 );
234#if DEBUGGING
235 if ( i < 0 || i > 3 ) {
236 NLUA_WARN( L, _( "Matrix column value not in range: %d" ), i );
237 i = CLAMP( 0, 3, i );
238 }
239 if ( j < 0 || j > 3 ) {
240 NLUA_WARN( L, _( "Matrix row value not in range: %d" ), j );
241 j = CLAMP( 0, 3, j );
242 }
243#endif /* DEBUGGING */
244 M->m[i][j] = v;
245 return 0;
246}
247
258static int transformL_scale( lua_State *L )
259{
260 const mat4 *M = luaL_checktransform( L, 1 );
261 double x = luaL_checknumber( L, 2 );
262 double y = luaL_checknumber( L, 3 );
263 double z = luaL_optnumber( L, 4, 1. );
264 mat4 out = *M;
265 mat4_scale( &out, x, y, z );
266 lua_pushtransform( L, out );
267 return 1;
268}
269
280static int transformL_translate( lua_State *L )
281{
282 const mat4 *M = luaL_checktransform( L, 1 );
283 double x = luaL_checknumber( L, 2 );
284 double y = luaL_checknumber( L, 3 );
285 double z = luaL_optnumber( L, 4, 0. );
286 mat4 out = *M;
287 mat4_translate( &out, x, y, z );
288 lua_pushtransform( L, out );
289 return 1;
290}
291
299static int transformL_rotate2d( lua_State *L )
300{
301 const mat4 *M = luaL_checktransform( L, 1 );
302 double a = luaL_checknumber( L, 2 );
303 mat4 out = *M;
304 mat4_rotate2d( &out, a );
305 lua_pushtransform( L, out );
306 return 1;
307}
308
321static int transformL_ortho( lua_State *L )
322{
323 double left = luaL_checknumber( L, 1 );
324 double right = luaL_checknumber( L, 2 );
325 double bottom = luaL_checknumber( L, 3 );
326 double top = luaL_checknumber( L, 4 );
327 double nearVal = luaL_checknumber( L, 5 );
328 double farVal = luaL_checknumber( L, 6 );
330 mat4_ortho( left, right, bottom, top, nearVal, farVal ) );
331 return 1;
332}
333
346static int transformL_applyPoint( lua_State *L )
347{
348 double gp[3], p[3];
349 mat4 *M = luaL_checktransform( L, 1 );
350 gp[0] = luaL_checknumber( L, 2 );
351 gp[1] = luaL_checknumber( L, 3 );
352 gp[2] = luaL_checknumber( L, 4 );
353
354 for ( int i = 0; i < 3; i++ )
355 p[i] = M->m[0][i] * gp[0] + M->m[1][i] * gp[1] + M->m[2][i] * gp[2] +
356 M->m[3][i];
357
358 lua_pushnumber( L, p[0] );
359 lua_pushnumber( L, p[1] );
360 lua_pushnumber( L, p[2] );
361 return 3;
362}
363
379static int transformL_applyDim( lua_State *L )
380{
381 double gp[3], p[3];
382 mat4 *M = luaL_checktransform( L, 1 );
383 gp[0] = luaL_checknumber( L, 2 );
384 gp[1] = luaL_checknumber( L, 3 );
385 gp[2] = luaL_checknumber( L, 4 );
386
387 for ( int i = 0; i < 3; i++ )
388 p[i] = M->m[0][i] * gp[0] + M->m[1][i] * gp[1] + M->m[2][i] * gp[2];
389
390 lua_pushnumber( L, p[0] );
391 lua_pushnumber( L, p[1] );
392 lua_pushnumber( L, p[2] );
393 return 3;
394}
void mat4_translate(mat4 *m, double x, double y, double z)
Translates a homogenous transformation matrix.
Definition mat4.c:137
mat4 mat4_identity(void)
Creates an identity matrix.
Definition mat4.c:335
void mat4_scale(mat4 *m, double x, double y, double z)
Scales a homogeneous transformation matrix.
Definition mat4.c:113
void mat4_mul(mat4 *out, const mat4 *m1, const mat4 *m2)
Multiplies two matrices (out = m1 * m2).
Definition mat4.c:46
mat4 mat4_ortho(double left, double right, double bottom, double top, double nearVal, double farVal)
Creates an orthographic projection matrix.
Definition mat4.c:347
void mat4_rotate2d(mat4 *m, double angle)
Rotates an angle, in radians, around the z axis.
Definition mat4.c:167
Header file with generic functions and naev-specifics.
#define CLAMP(a, b, x)
Definition naev.h:41
static int transformL_applyDim(lua_State *L)
Applies a transformation to a dimension.
static int transformL_scale(lua_State *L)
Applies scaling to a transform.
static int transformL_applyPoint(lua_State *L)
Applies a transformation to a point.
static int transformL_tostring(lua_State *L)
Gets a string representing the transform.
static int transformL_mul(lua_State *L)
Multiplies two transforms (A*B).
static int transformL_rotate2d(lua_State *L)
Applies a 2D rotation (along Z-axis) to a transform.
static int transformL_ortho(lua_State *L)
Creates an orthogonal matrix.
static int transformL_new(lua_State *L)
Creates a new identity transform.Gets a transform.
mat4 * lua_pushtransform(lua_State *L, mat4 transform)
Pushes a transform on the stack.
int lua_istransform(lua_State *L, int ind)
Checks to see if ind is a transform.
mat4 * luaL_checktransform(lua_State *L, int ind)
Gets transform at index or raises error if there is no transform at index.
static int transformL_set(lua_State *L)
Sets an element of a transform.
static int transformL_translate(lua_State *L)
Applies translation to a transform.
static int transformL_get(lua_State *L)
Gets all the values of the transform.
mat4 * lua_totransform(lua_State *L, int ind)
Lua bindings to interact with transforms.
static const luaL_Reg transformL_methods[]
static int transformL_eq(lua_State *L)
Compares two transforms to see if they are the same.
int nlua_loadTransform(nlua_env env)
Loads the transform library.
static cholmod_common C
Definition safelanes.c:106
Definition mat4.h:12