naev 0.12.5
nlua_vec2.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
12#include <lauxlib.h>
13
14#include "naev.h"
16
17#include "nlua_vec2.h"
18
19#include "collision.h"
20#include "nluadef.h"
21
22/* Vector metatable methods */
23static int vectorL_new( lua_State *L );
24static int vectorL_newP( lua_State *L );
25static int vectorL_copy( lua_State *L );
26static int vectorL_tostring( lua_State *L );
27static int vectorL_add__( lua_State *L );
28static int vectorL_add( lua_State *L );
29static int vectorL_sub__( lua_State *L );
30static int vectorL_sub( lua_State *L );
31static int vectorL_mul__( lua_State *L );
32static int vectorL_mul( lua_State *L );
33static int vectorL_div__( lua_State *L );
34static int vectorL_div( lua_State *L );
35static int vectorL_unm( lua_State *L );
36static int vectorL_dot( lua_State *L );
37static int vectorL_cross( lua_State *L );
38static int vectorL_get( lua_State *L );
39static int vectorL_polar( lua_State *L );
40static int vectorL_set( lua_State *L );
41static int vectorL_setP( lua_State *L );
42static int vectorL_distance( lua_State *L );
43static int vectorL_distance2( lua_State *L );
44static int vectorL_mod( lua_State *L );
45static int vectorL_angle( lua_State *L );
46static int vectorL_normalize( lua_State *L );
47static int vectorL_collideLineLine( lua_State *L );
48static int vectorL_collideCircleLine( lua_State *L );
49
50static const luaL_Reg vector_methods[] = {
51 { "new", vectorL_new },
52 { "newP", vectorL_newP },
53 { "copy", vectorL_copy },
54 { "__tostring", vectorL_tostring },
55 { "__add", vectorL_add },
56 { "add", vectorL_add__ },
57 { "__sub", vectorL_sub },
58 { "sub", vectorL_sub__ },
59 { "__mul", vectorL_mul },
60 { "mul", vectorL_mul__ },
61 { "__div", vectorL_div },
62 { "div", vectorL_div__ },
63 { "__unm", vectorL_unm },
64 { "dot", vectorL_dot },
65 { "cross", vectorL_cross },
66 { "get", vectorL_get },
67 { "polar", vectorL_polar },
68 { "set", vectorL_set },
69 { "setP", vectorL_setP },
70 { "dist", vectorL_distance },
71 { "dist2", vectorL_distance2 },
72 { "mod", vectorL_mod },
73 { "angle", vectorL_angle },
74 { "normalize", vectorL_normalize },
75 { "collideLineLine", vectorL_collideLineLine },
76 { "collideCircleLine", vectorL_collideCircleLine },
77 { 0, 0 } };
78
85int nlua_loadVector( nlua_env env )
86{
87 nlua_register( env, VECTOR_METATABLE, vector_methods, 1 );
88 return 0;
89}
90
119vec2 *lua_tovector( lua_State *L, int ind )
120{
121 return (vec2 *)lua_touserdata( L, ind );
122}
123
130vec2 *luaL_checkvector( lua_State *L, int ind )
131{
132 if ( lua_isvector( L, ind ) )
133 return (vec2 *)lua_touserdata( L, ind );
134 luaL_typerror( L, ind, VECTOR_METATABLE );
135 return NULL;
136}
137
145vec2 *lua_pushvector( lua_State *L, vec2 vec )
146{
147 vec2 *v = (vec2 *)lua_newuserdata( L, sizeof( vec2 ) );
148 *v = vec;
149 luaL_getmetatable( L, VECTOR_METATABLE );
150 lua_setmetatable( L, -2 );
151 return v;
152}
153
161int lua_isvector( lua_State *L, int ind )
162{
163 int ret;
164
165 if ( lua_getmetatable( L, ind ) == 0 )
166 return 0;
167 lua_getfield( L, LUA_REGISTRYINDEX, VECTOR_METATABLE );
168
169 ret = 0;
170 if ( lua_rawequal( L, -1, -2 ) ) /* does it have the correct mt? */
171 ret = 1;
172
173 lua_pop( L, 2 ); /* remove both metatables */
174 return ret;
175}
176
188static int vectorL_new( lua_State *L )
189{
190 vec2 v;
191 double x, y;
192
193 if ( !lua_isnoneornil( L, 1 ) )
194 x = luaL_checknumber( L, 1 );
195 else
196 x = 0.;
197
198 if ( !lua_isnoneornil( L, 2 ) )
199 y = luaL_checknumber( L, 2 );
200 else
201 y = x;
202
203 vec2_cset( &v, x, y );
204 lua_pushvector( L, v );
205 return 1;
206}
207
220static int vectorL_newP( lua_State *L )
221{
222 vec2 v;
223 double m, a;
224
225 if ( !lua_isnoneornil( L, 1 ) )
226 m = luaL_checknumber( L, 1 );
227 else
228 m = 0.;
229
230 if ( !lua_isnoneornil( L, 2 ) )
231 a = luaL_checknumber( L, 2 );
232 else
233 a = 0.;
234
235 vec2_pset( &v, m, a );
236 lua_pushvector( L, v );
237 return 1;
238}
239
247static int vectorL_copy( lua_State *L )
248{
249 const vec2 *v = luaL_checkvector( L, 1 );
250 lua_pushvector( L, *v );
251 return 1;
252}
253
261static int vectorL_tostring( lua_State *L )
262{
263 char buf[STRMAX_SHORT];
264 const vec2 *v = luaL_checkvector( L, 1 );
265 snprintf( buf, sizeof( buf ), "vec2( %g, %g )", v->x, v->y );
266 lua_pushstring( L, buf );
267 return 1;
268}
269
286static int vectorL_add( lua_State *L )
287{
288 vec2 vout, *v1;
289 double x, y;
290
291 if ( lua_isnumber( L, 1 ) ) {
292 x = y = lua_tonumber( L, 1 );
293 v1 = luaL_checkvector( L, 2 );
294 } else {
295 /* Get self. */
296 v1 = luaL_checkvector( L, 1 );
297
298 /* Get rest of parameters. */
299 if ( lua_isvector( L, 2 ) ) {
300 const vec2 *v2 = lua_tovector( L, 2 );
301 x = v2->x;
302 y = v2->y;
303 } else {
304 x = luaL_checknumber( L, 2 );
305 if ( !lua_isnoneornil( L, 3 ) )
306 y = luaL_checknumber( L, 3 );
307 else
308 y = x;
309 }
310 }
311
312 /* Actually add it */
313 vec2_cset( &vout, v1->x + x, v1->y + y );
314 lua_pushvector( L, vout );
315
316 return 1;
317}
318static int vectorL_add__( lua_State *L )
319{
320 vec2 *v1;
321 double x, y;
322
323 /* Get self. */
324 v1 = luaL_checkvector( L, 1 );
325
326 /* Get rest of parameters. */
327 if ( lua_isvector( L, 2 ) ) {
328 const vec2 *v2 = lua_tovector( L, 2 );
329 x = v2->x;
330 y = v2->y;
331 } else {
332 x = luaL_checknumber( L, 2 );
333 if ( !lua_isnoneornil( L, 3 ) )
334 y = luaL_checknumber( L, 3 );
335 else
336 y = x;
337 }
338
339 /* Actually add it */
340 vec2_cset( v1, v1->x + x, v1->y + y );
341 lua_pushvector( L, *v1 );
342
343 return 1;
344}
345
362static int vectorL_sub( lua_State *L )
363{
364 const vec2 *v1;
365 vec2 vout;
366 double x, y;
367
368 /* Get self. */
369 v1 = luaL_checkvector( L, 1 );
370
371 /* Get rest of parameters. */
372 if ( lua_isvector( L, 2 ) ) {
373 const vec2 *v2 = lua_tovector( L, 2 );
374 x = v2->x;
375 y = v2->y;
376 } else {
377 x = luaL_checknumber( L, 2 );
378 if ( !lua_isnoneornil( L, 3 ) )
379 y = luaL_checknumber( L, 3 );
380 else
381 y = x;
382 }
383
384 /* Actually add it */
385 vec2_cset( &vout, v1->x - x, v1->y - y );
386 lua_pushvector( L, vout );
387 return 1;
388}
389static int vectorL_sub__( lua_State *L )
390{
391 vec2 *v1;
392 double x, y;
393
394 /* Get self. */
395 v1 = luaL_checkvector( L, 1 );
396
397 /* Get rest of parameters. */
398 if ( lua_isvector( L, 2 ) ) {
399 const vec2 *v2 = lua_tovector( L, 2 );
400 x = v2->x;
401 y = v2->y;
402 } else {
403 x = luaL_checknumber( L, 2 );
404 if ( !lua_isnoneornil( L, 3 ) )
405 y = luaL_checknumber( L, 3 );
406 else
407 y = x;
408 }
409
410 /* Actually add it */
411 vec2_cset( v1, v1->x - x, v1->y - y );
412 lua_pushvector( L, *v1 );
413 return 1;
414}
415
427static int vectorL_mul( lua_State *L )
428{
429 vec2 vout;
430
431 if ( lua_isnumber( L, 1 ) ) {
432 double d = lua_tonumber( L, 1 );
433 const vec2 *v = luaL_checkvector( L, 2 );
434 vec2_cset( &vout, v->x * d, v->y * d );
435 } else {
436 if ( lua_isnumber( L, 2 ) ) {
437 const vec2 *v = luaL_checkvector( L, 1 );
438 double d = lua_tonumber( L, 2 );
439 vec2_cset( &vout, v->x * d, v->y * d );
440 } else {
441 const vec2 *v1 = luaL_checkvector( L, 1 );
442 const vec2 *v2 = luaL_checkvector( L, 2 );
443 vec2_cset( &vout, v1->x * v2->x, v1->y * v2->y );
444 }
445 }
446
447 /* Actually add it */
448 lua_pushvector( L, vout );
449 return 1;
450}
451static int vectorL_mul__( lua_State *L )
452{
453 vec2 *v1 = luaL_checkvector( L, 1 );
454 if ( lua_isnumber( L, 2 ) ) {
455 double mod = luaL_checknumber( L, 2 );
456 vec2_cset( v1, v1->x * mod, v1->y * mod );
457 } else {
458 const vec2 *v2 = luaL_checkvector( L, 2 );
459 vec2_cset( v1, v1->x * v2->x, v1->y * v2->y );
460 }
461
462 /* Actually add it */
463 lua_pushvector( L, *v1 );
464 return 1;
465}
466
478static int vectorL_div( lua_State *L )
479{
480 vec2 vout;
481 const vec2 *v1 = luaL_checkvector( L, 1 );
482 if ( lua_isnumber( L, 2 ) ) {
483 double mod = lua_tonumber( L, 2 );
484 vec2_cset( &vout, v1->x / mod, v1->y / mod );
485 } else {
486 const vec2 *v2 = luaL_checkvector( L, 2 );
487 vec2_cset( &vout, v1->x / v2->x, v1->y / v2->y );
488 }
489
490 lua_pushvector( L, vout );
491 return 1;
492}
493static int vectorL_div__( lua_State *L )
494{
495 vec2 *v1 = luaL_checkvector( L, 1 );
496 if ( lua_isnumber( L, 2 ) ) {
497 double mod = lua_tonumber( L, 2 );
498 vec2_cset( v1, v1->x / mod, v1->y / mod );
499 } else {
500 const vec2 *v2 = luaL_checkvector( L, 2 );
501 vec2_cset( v1, v1->x / v2->x, v1->y / v2->y );
502 }
503
504 lua_pushvector( L, *v1 );
505 return 1;
506}
507static int vectorL_unm( lua_State *L )
508{
509 vec2 vout;
510 const vec2 *vin = luaL_checkvector( L, 1 );
511 vec2_cset( &vout, -vin->x, -vin->y );
512 lua_pushvector( L, vout );
513 return 1;
514}
515
524static int vectorL_dot( lua_State *L )
525{
526 const vec2 *a = luaL_checkvector( L, 1 );
527 const vec2 *b = luaL_checkvector( L, 2 );
528 lua_pushnumber( L, a->x * b->x + a->y * b->y );
529 return 1;
530}
531
540static int vectorL_cross( lua_State *L )
541{
542 const vec2 *a = luaL_checkvector( L, 1 );
543 const vec2 *b = luaL_checkvector( L, 2 );
544 lua_pushnumber( L, a->x * b->y - a->y * b->x );
545 return 1;
546}
547
558static int vectorL_get( lua_State *L )
559{
560 const vec2 *v1 = luaL_checkvector( L, 1 );
561 /* Push the vector. */
562 lua_pushnumber( L, v1->x );
563 lua_pushnumber( L, v1->y );
564 return 2;
565}
566
579static int vectorL_polar( lua_State *L )
580{
581 const vec2 *v1 = luaL_checkvector( L, 1 );
582 lua_pushnumber( L, VMOD( *v1 ) );
583 lua_pushnumber( L, VANGLE( *v1 ) );
584 return 2;
585}
586
597static int vectorL_set( lua_State *L )
598{
599 vec2 *v1;
600 double x, y;
601
602 /* Get parameters. */
603 v1 = luaL_checkvector( L, 1 );
604 x = luaL_checknumber( L, 2 );
605 y = luaL_checknumber( L, 3 );
606
607 vec2_cset( v1, x, y );
608 return 0;
609}
610
621static int vectorL_setP( lua_State *L )
622{
623 vec2 *v1;
624 double m, a;
625
626 /* Get parameters. */
627 v1 = luaL_checkvector( L, 1 );
628 m = luaL_checknumber( L, 2 );
629 a = luaL_checknumber( L, 3 );
630
631 vec2_pset( v1, m, a );
632 return 0;
633}
634
648static int vectorL_distance( lua_State *L )
649{
650 double dist;
651 const vec2 *v1 = luaL_checkvector( L, 1 );
652
653 /* Get rest of parameters. */
654 if ( !lua_isnoneornil( L, 2 ) ) {
655 const vec2 *v2 = luaL_checkvector( L, 2 );
656 dist = vec2_dist( v1, v2 );
657 } else
658 dist = vec2_odist( v1 );
659
660 /* Return the distance. */
661 lua_pushnumber( L, dist );
662 return 1;
663}
664
679static int vectorL_distance2( lua_State *L )
680{
681 double dist2;
682 const vec2 *v1 = luaL_checkvector( L, 1 );
683
684 /* Get rest of parameters. */
685 if ( !lua_isnoneornil( L, 2 ) ) {
686 const vec2 *v2 = luaL_checkvector( L, 2 );
687 dist2 = vec2_dist2( v1, v2 );
688 } else
689 dist2 = vec2_odist2( v1 );
690
691 /* Return the distance. */
692 lua_pushnumber( L, dist2 );
693 return 1;
694}
695
702static int vectorL_mod( lua_State *L )
703{
704 const vec2 *v = luaL_checkvector( L, 1 );
705 lua_pushnumber( L, VMOD( *v ) );
706 return 1;
707}
708
715static int vectorL_angle( lua_State *L )
716{
717 const vec2 *v = luaL_checkvector( L, 1 );
718 lua_pushnumber( L, VANGLE( *v ) );
719 return 1;
720}
721
729static int vectorL_normalize( lua_State *L )
730{
731 vec2 *v = luaL_checkvector( L, 1 );
732 double n = luaL_optnumber( L, 2, 1. );
733 double m = n / MAX( VMOD( *v ), DOUBLE_TOL );
734 v->x *= m;
735 v->y *= m;
736 lua_pushvector( L, *v );
737 return 1;
738}
739
751static int vectorL_collideLineLine( lua_State *L )
752{
753 const vec2 *s1 = luaL_checkvector( L, 1 );
754 const vec2 *e1 = luaL_checkvector( L, 2 );
755 const vec2 *s2 = luaL_checkvector( L, 3 );
756 const vec2 *e2 = luaL_checkvector( L, 4 );
757 vec2 crash;
758 int ret = CollideLineLine( s1->x, s1->y, e1->x, e1->y, s2->x, s2->y, e2->x,
759 e2->y, &crash );
760 lua_pushinteger( L, ret );
761 lua_pushvector( L, crash );
762 return 2;
763}
764
777static int vectorL_collideCircleLine( lua_State *L )
778{
779 const vec2 *center, *p1, *p2;
780 vec2 crash[2];
781 double radius;
782
783 center = luaL_checkvector( L, 1 );
784 radius = luaL_checknumber( L, 2 );
785 p1 = luaL_checkvector( L, 3 );
786 p2 = luaL_checkvector( L, 4 );
787
788 int cnt = CollideLineCircle( p1, p2, center, radius, crash );
789 if ( cnt > 0 )
790 lua_pushvector( L, crash[0] );
791 if ( cnt > 1 )
792 lua_pushvector( L, crash[1] );
793
794 return cnt;
795}
int CollideLineCircle(const vec2 *p1, const vec2 *p2, const vec2 *cc, double cr, vec2 crash[2])
Checks to see if a line collides with a circle.
Definition collision.c:1030
int CollideLineLine(double s1x, double s1y, double e1x, double e1y, double s2x, double s2y, double e2x, double e2y, vec2 *crash)
Checks to see if two lines collide.
Definition collision.c:526
Header file with generic functions and naev-specifics.
#define MAX(x, y)
Definition naev.h:37
static int vectorL_distance2(lua_State *L)
Gets the squared distance from the Vec2 (saves a sqrt())
Definition nlua_vec2.c:679
static int vectorL_collideCircleLine(lua_State *L)
Computes the intersection of a line segment and a circle.
Definition nlua_vec2.c:777
static int vectorL_collideLineLine(lua_State *L)
Sees if two line segments collide.
Definition nlua_vec2.c:751
static const luaL_Reg vector_methods[]
Definition nlua_vec2.c:50
static int vectorL_mod(lua_State *L)
Gets the modulus of the vector. Lua function parameter: Vec2 v Vector to get modulus of....
Definition nlua_vec2.c:702
static int vectorL_dot(lua_State *L)
Dot product of two vectors.
Definition nlua_vec2.c:524
static int vectorL_cross(lua_State *L)
Cross product of two vectors.
Definition nlua_vec2.c:540
static int vectorL_set(lua_State *L)
Sets the vector by cartesian coordinates.
Definition nlua_vec2.c:597
static int vectorL_div(lua_State *L)
Divides a vector by a number.
Definition nlua_vec2.c:478
static int vectorL_setP(lua_State *L)
Sets the vector by polar coordinates.
Definition nlua_vec2.c:621
static int vectorL_angle(lua_State *L)
Gets the angle of the vector. Lua function parameter: Vec2 v Vector to get angle of....
Definition nlua_vec2.c:715
static int vectorL_normalize(lua_State *L)
Normalizes a vector. Lua function parameter: Vec2 v Vector to normalize. Lua function parameter:[opt=...
Definition nlua_vec2.c:729
static int vectorL_mul(lua_State *L)
Multiplies a vector by a number.
Definition nlua_vec2.c:427
int nlua_loadVector(nlua_env env)
Loads the vector metatable.
Definition nlua_vec2.c:85
static int vectorL_copy(lua_State *L)
Copies a vector.
Definition nlua_vec2.c:247
int lua_isvector(lua_State *L, int ind)
Checks to see if ind is a vector.
Definition nlua_vec2.c:161
static int vectorL_add(lua_State *L)
Adds two vectors or a vector and some cartesian coordinates.
Definition nlua_vec2.c:286
static int vectorL_newP(lua_State *L)
Creates a new vector using polar coordinates.
Definition nlua_vec2.c:220
static int vectorL_tostring(lua_State *L)
Converts a vector to a string.
Definition nlua_vec2.c:261
static int vectorL_get(lua_State *L)
Gets the cartesian positions of the vector.
Definition nlua_vec2.c:558
vec2 * luaL_checkvector(lua_State *L, int ind)
Gets vector at index making sure type is valid.
Definition nlua_vec2.c:130
static int vectorL_sub(lua_State *L)
Subtracts two vectors or a vector and some cartesian coordinates.
Definition nlua_vec2.c:362
static int vectorL_distance(lua_State *L)
Gets the distance from the Vec2.
Definition nlua_vec2.c:648
static int vectorL_polar(lua_State *L)
Gets polar coordinates of a vector.
Definition nlua_vec2.c:579
vec2 * lua_tovector(lua_State *L, int ind)
Represents a 2D vector in Lua.
Definition nlua_vec2.c:119
vec2 * lua_pushvector(lua_State *L, vec2 vec)
Pushes a vector on the stack.
Definition nlua_vec2.c:145
static int vectorL_new(lua_State *L)
Creates a new vector.
Definition nlua_vec2.c:188
static const double d[]
Definition rng.c:263
Represents a 2d vector.
Definition vec2.h:45
double y
Definition vec2.h:47
double x
Definition vec2.h:46