27 float x1,
float y1,
float x2,
float y2,
vec2* crash );
37 xmlNodePtr cur = node->children;
39 if (xml_isNode(cur,
"x")) {
41 char *list = xml_get(cur);
43 char *ch = SDL_strtokr(list,
",", &saveptr);
52 ch = SDL_strtokr(NULL,
",", &saveptr);
55 else if (xml_isNode(cur,
"y")) {
57 char *list = xml_get(cur);
59 char *ch = SDL_strtokr(list,
",", &saveptr);
68 ch = SDL_strtokr(NULL,
",", &saveptr);
71 }
while (xml_nextNode(cur));
75 WARN(_(
"Polygon with mismatch of number of |x|=%d and |y|=%d coordinates detected!"), polygon->
npt,
array_size(polygon->
y) );
104 const glTexture* bt,
const int bsx,
const int bsy,
const vec2* bp,
108 int ax1,ax2, ay1,ay2;
109 int bx1,bx2, by1,by2;
110 int inter_x0, inter_x1, inter_y0, inter_y1;
112 int abx,aby, bbx, bby;
116 if (at->
trans == NULL) {
117 WARN(_(
"Texture '%s' has no transparency map"), at->
name);
120 if (bt->
trans == NULL) {
121 WARN(_(
"Texture '%s' has no transparency map"), bt->
name);
127 ax1 = (int)VX(*ap) - (int)(at->
sw)/2;
128 ay1 = (int)VY(*ap) - (int)(at->
sh)/2;
129 ax2 = ax1 + (int)(at->
sw) - 1;
130 ay2 = ay1 + (int)(at->
sh) - 1;
133 bx1 = (int)VX(*bp) - (int)(bt->
sw)/2;
134 by1 = (int)VY(*bp) - (int)(bt->
sh)/2;
135 bx2 = bx1 + bt->
sw - 1;
136 by2 = by1 + bt->
sh - 1;
139 if ((bx2 < ax1) || (ax2 < bx1))
return 0;
140 if ((by2 < ay1) || (ay2 < by1))
return 0;
143 inter_x0 =
MAX( ax1, bx1 );
144 inter_x1 =
MIN( ax2, bx2 );
145 inter_y0 =
MAX( ay1, by1 );
146 inter_y1 =
MIN( ay2, by2 );
149 rasy = at->
sy - asy - 1;
150 rbsy = bt->
sy - bsy - 1;
153 abx = asx*(int)(at->
sw) - ax1;
154 aby = rasy*(int)(at->
sh) - ay1;
155 bbx = bsx*(int)(bt->
sw) - bx1;
156 bby = rbsy*(int)(bt->
sh) - by1;
158 for (y=inter_y0; y<=inter_y1; y++)
159 for (x=inter_x0; x<=inter_x1; x++)
186 const glTexture* bt,
const int bsx,
const int bsy,
const vec2* bp,
190 int ax1,ax2, ay1,ay2;
191 int bx1,bx2, by1,by2;
192 int inter_x0, inter_x1, inter_y0, inter_y1;
198 if (bt->
trans == NULL) {
199 WARN(_(
"Texture '%s' has no transparency map"), bt->
name);
205 ax1 = (int)VX(*ap) + (int)(at->
xmin);
206 ay1 = (int)VY(*ap) + (int)(at->
ymin);
207 ax2 = (int)VX(*ap) + (int)(at->
xmax);
208 ay2 = (int)VY(*ap) + (int)(at->
ymax);
211 bx1 = (int)VX(*bp) - (int)(bt->
sw)/2;
212 by1 = (int)VY(*bp) - (int)(bt->
sh)/2;
213 bx2 = bx1 + bt->
sw - 1;
214 by2 = by1 + bt->
sh - 1;
217 if ((bx2 < ax1) || (ax2 < bx1))
return 0;
218 if ((by2 < ay1) || (ay2 < by1))
return 0;
221 inter_x0 =
MAX( ax1, bx1 );
222 inter_x1 =
MIN( ax2, bx2 );
223 inter_y0 =
MAX( ay1, by1 );
224 inter_y1 =
MIN( ay2, by2 );
227 rbsy = bt->
sy - bsy - 1;
230 bbx = bsx*(int)(bt->
sw) - bx1;
231 bby = rbsy*(int)(bt->
sh) - by1;
232 for (y=inter_y0; y<=inter_y1; y++) {
233 for (x=inter_x0; x<=inter_x1; x++) {
263 int ax1,ax2, ay1,ay2;
264 int bx1,bx2, by1,by2;
265 int inter_x0, inter_x1, inter_y0, inter_y1;
266 float x1, y1, x2, y2;
269 ax1 = (int)VX(*ap) + (int)(at->
xmin);
270 ay1 = (int)VY(*ap) + (int)(at->
ymin);
271 ax2 = (int)VX(*ap) + (int)(at->
xmax);
272 ay2 = (int)VY(*ap) + (int)(at->
ymax);
275 bx1 = (int)VX(*bp) + (int)(bt->
xmin);
276 by1 = (int)VY(*bp) + (int)(bt->
ymin);
277 bx2 = (int)VX(*bp) + (int)(bt->
xmax);
278 by2 = (int)VY(*bp) + (int)(bt->
ymax);
281 if ((bx2 < ax1) || (ax2 < bx1))
return 0;
282 if ((by2 < ay1) || (ay2 < by1))
return 0;
285 inter_x0 =
MAX( ax1, bx1 );
286 inter_x1 =
MIN( ax2, bx2 );
287 inter_y0 =
MAX( ay1, by1 );
288 inter_y1 =
MIN( ay2, by2 );
291 for (
int i=0; i<=bt->
npt-1; i++) {
293 xabs = bt->
x[i] + VX(*bp);
294 yabs = bt->
y[i] + VY(*bp);
296 if ((xabs<inter_x0) || (xabs>inter_x1) ||
297 (yabs<inter_y0) || (yabs>inter_y1)) {
299 crash->
x = (int)xabs;
300 crash->
y = (int)yabs;
307 x1 = bt->
x[0] + VX(*bp);
308 y1 = bt->
y[0] + VY(*bp);
309 x2 = bt->
x[bt->
npt-1] + VX(*bp);
310 y2 = bt->
y[bt->
npt-1] + VY(*bp);
313 for (
int i=0; i<=bt->
npt-2; i++) {
314 x1 = bt->
x[i] + VX(*bp);
315 y1 = bt->
y[i] + VY(*bp);
316 x2 = bt->
x[i+1] + VX(*bp);
317 y2 = bt->
y[i+1] + VY(*bp);
336 rpolygon->
npt = ipolygon->
npt;
337 rpolygon->
x = malloc( ipolygon->
npt*
sizeof(
float) );
338 rpolygon->
y = malloc( ipolygon->
npt*
sizeof(
float) );
347 for (
int i=0; i<=rpolygon->
npt-1; i++) {
348 float d = ipolygon->
x[i] * ct - ipolygon->
y[i] *
st;
353 d = ipolygon->
x[i] *
st + ipolygon->
y[i] * ct ;
372 float vprod, sprod, angle;
373 float dxi, dxip, dyi, dyip;
380 for (
int i=0; i<=at->
npt-2; i++) {
381 dxi = at->
x[i] +VX(*ap)-x;
382 dxip = at->
x[i+1]+VX(*ap)-x;
383 dyi = at->
y[i] +VY(*ap)-y;
384 dyip = at->
y[i+1]+VY(*ap)-y;
385 sprod = dxi * dxip + dyi * dyip;
386 vprod = dxi * dyip - dyi * dxip;
387 angle += atan2(vprod, sprod);
389 dxi = at->
x[at->
npt-1] + VX(*ap) - x;
390 dxip = at->
x[0] + VX(*ap) - x;
391 dyi = at->
y[at->
npt-1] + VY(*ap)- y;
392 dyip = at->
y[0] + VY(*ap) - y;
393 sprod = dxi * dxip + dyi * dyip;
394 vprod = dxi * dyip - dyi * dxip;
395 angle += atan2(vprod, sprod);
397 if (
FABS(angle) < 1e-5)
416 float x1,
float y1,
float x2,
float y2,
vec2* crash )
418 float xi, xip, yi, yip;
422 xi = at->
x[at->
npt-1] + ap->
x;
423 xip = at->
x[0] + ap->
x;
424 yi = at->
y[at->
npt-1] + ap->
y;
425 yip = at->
y[0] + ap->
y;
428 for (
int i=0; i<=at->
npt-2; i++) {
429 xi = at->
x[i] + ap->
x;
430 xip = at->
x[i+1] + ap->
x;
431 yi = at->
y[i] + ap->
y;
432 yip = at->
y[i+1] + ap->
y;
456 double s2x,
double s2y,
double e2x,
double e2y,
vec2* crash )
458 double ua_t, ub_t, u_b;
460 ua_t = (e2x - s2x) * (s1y - s2y) - (e2y - s2y) * (s1x - s2x);
461 ub_t = (e1x - s1x) * (s1y - s2y) - (e1y - s1y) * (s1x - s2x);
462 u_b = (e2y - s2y) * (e1x - s1x) - (e2x - s2x) * (e1y - s1y);
470 if ((0. <= ua) && (ua <= 1.) && (0. <= ub) && (ub <= 1.)) {
471 crash->
x = s1x + ua * (e1x - s1x);
472 crash->
y = s1y + ua * (e1y - s1y);
481 if ((ua_t == 0.) || (ub_t == 0.))
509 const glTexture* bt,
const int bsx,
const int bsy,
const vec2* bp,
512 int x,y, rbsy, bbx,bby;
513 double ep[2], bl[2], tr[2], v[2], mod;
515 vec2 tmp_crash, border[2];
518 if (bt->
trans == NULL) {
519 WARN(_(
"Texture '%s' has no transparency map"), bt->
name);
524 ep[0] = ap->
x + al*cos(ad);
525 ep[1] = ap->
y + al*sin(ad);
528 tr[0] = bp->
x + bt->
sw/2.;
529 tr[1] = bp->
y + bt->
sh/2.;
531 bl[0] = bp->
x - bt->
sw/2.;
532 bl[1] = bp->
y - bt->
sh/2.;
540 bl[0], bl[1], bl[0], tr[1], &tmp_crash) == 1) {
541 border[hits].x = tmp_crash.
x;
542 border[hits].y = tmp_crash.
y;
547 bl[0], tr[1], tr[0], tr[1], &tmp_crash) == 1) {
548 border[hits].x = tmp_crash.
x;
549 border[hits].y = tmp_crash.
y;
555 tr[0], tr[1], tr[0], bl[1], &tmp_crash) == 1) {
556 border[hits].x = tmp_crash.
x;
557 border[hits].y = tmp_crash.
y;
562 tr[0], bl[1], bl[0], bl[1], &tmp_crash) == 1) {
563 border[hits].x = tmp_crash.
x;
564 border[hits].y = tmp_crash.
y;
583 v[0] = border[1].x - border[0].x;
584 v[1] = border[1].y - border[0].y;
586 mod = MOD(v[0],v[1])/2.;
591 rbsy = bt->
sy - bsy - 1;
593 bbx = bsx*(int)(bt->
sw);
594 bby = rbsy*(int)(bt->
sh);
597 x = border[0].x - bl[0] + v[0];
598 y = border[0].y - bl[1] + v[1];
599 while ((x > 0.) && (x < bt->sw) && (y > 0.) && (y < bt->sh)) {
601 if (!
gl_isTrans(bt, bbx+(
int)x, bby+(
int)y)) {
602 crash[real_hits].
x = x + bl[0];
603 crash[real_hits].
y = y + bl[1];
612 x = border[1].x - bl[0] - v[0];
613 y = border[1].y - bl[1] - v[1];
614 while ((x > 0.) && (x < bt->sw) && (y > 0.) && (y < bt->sh)) {
616 if (!
gl_isTrans(bt, bbx+(
int)x, bby+(
int)y)) {
617 crash[real_hits].
x = x + bl[0];
618 crash[real_hits].
y = y + bl[1];
632 if (real_hits == 1) {
633 crash[1].
x = crash[0].
x;
634 crash[1].
y = crash[0].
y;
661 double xi, yi, xip, yip;
666 ep[0] = ap->
x + al*cos(ad);
667 ep[1] = ap->
y + al*sin(ad);
670 vectnull( &tmp_crash );
674 crash[real_hits].
x = ap->
x;
675 crash[real_hits].
y = ap->
y;
681 crash[real_hits].
x = ep[0];
682 crash[real_hits].
y = ep[1];
691 if (real_hits == 0) {
695 tr[0] = bp->
x + (double)bt->
xmax;
696 tr[1] = bp->
y + (double)bt->
ymax;
698 bl[0] = bp->
x + (double)bt->
xmin;
699 bl[1] = bp->
y + (double)bt->
ymin;
707 bl[0], bl[1], bl[0], tr[1], &tmp_crash) == 1)
712 bl[0], tr[1], tr[0], tr[1], &tmp_crash) == 1)
717 tr[0], tr[1], tr[0], bl[1], &tmp_crash) == 1)
722 tr[0], bl[1], bl[0], bl[1], &tmp_crash) == 1)
733 xi = (double)bt->
x[bt->
npt-1] + bp->
x;
734 xip = (double)bt->
x[0] + bp->
x;
735 yi = (double)bt->
y[bt->
npt-1] + bp->
y;
736 yip = (double)bt->
y[0] + bp->
y;
738 xi, yi, xip, yip, &tmp_crash) ) {
739 crash[real_hits].
x = tmp_crash.
x;
740 crash[real_hits].
y = tmp_crash.
y;
745 for (
int i=0; i<=bt->
npt-2; i++) {
746 xi = (double)bt->
x[i] + bp->
x;
747 xip = (double)bt->
x[i+1] + bp->
x;
748 yi = (double)bt->
y[i] + bp->
y;
749 yip = (double)bt->
y[i+1] + bp->
y;
751 xi, yi, xip, yip, &tmp_crash) ) {
752 crash[real_hits].
x = tmp_crash.
x;
753 crash[real_hits].
y = tmp_crash.
y;
766 if (real_hits == 1) {
767 crash[1].
x = crash[0].
x;
768 crash[1].
y = crash[0].
y;
798 vectnull( &tmp_crash[0] );
799 vectnull( &tmp_crash[1] );
802 p1.
x = bp->
x + (double)bt->
xmax;
803 p1.
y = bp->
y + (double)bt->
ymax;
805 p2.
x = bp->
x + (double)bt->
xmin;
806 p2.
y = bp->
y + (double)bt->
ymin;
809 if ((ap->
x-ar > p1.
x) && (ap->
x+ar < p2.
x) &&
810 (ap->
y-ar > p1.
y) && (ap->
y+ar < p2.
y))
816 p1.
x = (double)bt->
x[bt->
npt-1] + bp->
x;
817 p2.
x = (double)bt->
x[0] + bp->
x;
818 p1.
y = (double)bt->
y[bt->
npt-1] + bp->
y;
819 p2.
y = (double)bt->
y[0] + bp->
y;
821 crash[real_hits].
x = tmp_crash[0].
x;
822 crash[real_hits].
y = tmp_crash[0].
y;
827 for (
int i=0; i<=bt->
npt-2; i++) {
828 p1.
x = (double)bt->
x[i] + bp->
x;
829 p2.
x = (double)bt->
x[i+1] + bp->
x;
830 p1.
y = (double)bt->
y[i] + bp->
y;
831 p2.
y = (double)bt->
y[i+1] + bp->
y;
833 crash[real_hits].
x = tmp_crash[0].
x;
834 crash[real_hits].
y = tmp_crash[0].
y;
847 if (real_hits == 1) {
848 crash[1].
x = crash[0].
x;
849 crash[1].
y = crash[0].
y;
869 const int bsx,
const int bsy,
const vec2* bp,
vec2* crash )
871 int r, acx,acy, ax1,ax2, ay1,ay2;
872 int bx1,bx2, by1,by2;
873 int inter_x0, inter_x1, inter_y0, inter_y1;
879 if (bt->
trans == NULL) {
880 WARN(_(
"Texture '%s' has no transparency map"), bt->
name);
895 bx1 = (int)VX(*bp) - (int)(bt->
sw)/2;
896 by1 = (int)VY(*bp) - (int)(bt->
sh)/2;
897 bx2 = bx1 + bt->
sw - 1;
898 by2 = by1 + bt->
sh - 1;
901 if ((bx2 < ax1) || (ax2 < bx1))
return 0;
902 if ((by2 < ay1) || (ay2 < by1))
return 0;
905 inter_x0 =
MAX( ax1, bx1 );
906 inter_x1 =
MIN( ax2, bx2 );
907 inter_y0 =
MAX( ay1, by1 );
908 inter_y1 =
MIN( ay2, by2 );
911 rbsy = bt->
sy - bsy - 1;
914 bbx = bsx*(int)(bt->
sw) - bx1;
915 bby = rbsy*(int)(bt->
sh) - by1;
916 for (
int y=inter_y0; y<=inter_y1; y++) {
917 for (
int x=inter_x0; x<=inter_x1; x++) {
920 if (
pow2(x-acx)+
pow2(y-acy) <= r*r) {
932static int linePointOnSegment(
double d1,
double x1,
double y1,
double x2,
double y2,
double x,
double y )
935 double d2 = hypot( x-x1, y-y1 );
936 double d3 = hypot( x2-x, y2-y );
937 return fabs(d1 - d2 - d3) < 1e-8;
940#define FX( A, B, C, x ) (-(A * x + C) / B)
941#define FY( A, B, C , y ) (-(B * y + C) / A)
953 const vec2 *cc,
double cr,
vec2 crash[2] )
964 double C = x2 * y1 - x1 * y2;
974 if (fabs(B) >= 1e-8) {
975 b = 2. * (A *
C + A * B * y0 -
pow2(B) * x0);
981 b = 2. * (B *
C + A * B * x0 -
pow2(A) * y0);
990 d1 = hypot( x2-x1, y2-y1 );
996 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
1004 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
1015 x = (-b +
d) / (2. * a);
1017 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
1022 x = (-b -
d) / (2. * a);
1024 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
1030 y = (-b +
d) / (2. * a);
1032 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
1037 y = (-b -
d) / (2. * a);
1039 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
1055 const vec2 *p2,
double r2,
vec2 crash[2] )
1057 double dist2 = vec2_dist2( p1, p2 );
1060 if (dist2 >
pow2(r1+r2))
1063 crash->
x = (p1->
x * r1 + p2->
x * r2) / (r1+r2);
1064 crash->
y = (p1->
y * r1 + p2->
y * r2) / (r1+r2);
1072 const vec2 *p2,
double r2 )
1074 double dist2 = vec2_dist2( p1, p2 );
1077 if (dist2 >
pow2(r1+r2))
1081 if (dist2 <=
pow2(fabs(r1-r2)))
1082 return M_PI *
pow2(
MIN(r1, r2) );
1086 if ((dist2==0.) && (r1==r2))
1087 return M_PI *
pow2(r1);
1091 double dist = sqrt( dist2 );
1092 double distc1 = (
pow2(r1) -
pow2(r2) + dist2) / (2. * dist);
1093 double distc2 = dist - distc1;
1094 double height = sqrt(
pow2(r1) -
pow2(distc1) );
1096 double ang1 = fmod( atan2( height, distc1 ) * 2. + 2.*M_PI, 2.*M_PI );
1097 double ang2 = fmod( atan2( height, distc2 ) * 2. + 2.*M_PI, 2.*M_PI );
1099 double A1 =
pow2(r1) / 2.0 * (ang1 - sin(ang1));
1100 double A2 =
pow2(r2) / 2.0 * (ang2 - sin(ang2));
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
int CollideCircleCircle(const vec2 *p1, double r1, const vec2 *p2, double r2, vec2 crash[2])
Computes the collision between two circles.
void RotatePolygon(CollPoly *rpolygon, CollPoly *ipolygon, float theta)
Rotates a polygon.
static int LineOnPolygon(const CollPoly *at, const vec2 *ap, float x1, float y1, float x2, float y2, vec2 *crash)
Checks whether or not a line intersects a polygon.
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.
int CollideLinePolygon(const vec2 *ap, double ad, double al, const CollPoly *bt, const vec2 *bp, vec2 crash[2])
Checks to see if a line collides with a polygon.
static int PointInPolygon(const CollPoly *at, const vec2 *ap, float x, float y)
Checks whether or not a point is inside a polygon.
int CollideLineSprite(const vec2 *ap, double ad, double al, const glTexture *bt, const int bsx, const int bsy, const vec2 *bp, vec2 crash[2])
Checks to see if a line collides with a sprite.
int CollideCircleSprite(const vec2 *ap, double ar, const glTexture *bt, const int bsx, const int bsy, const vec2 *bp, vec2 *crash)
Checks whether or not a sprite collides with a polygon.
void LoadPolygon(CollPoly *polygon, xmlNodePtr node)
Loads a polygon from an xml node.
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.
int CollideSprite(const glTexture *at, const int asx, const int asy, const vec2 *ap, const glTexture *bt, const int bsx, const int bsy, const vec2 *bp, vec2 *crash)
Checks whether or not two sprites collide.
int CollideCirclePolygon(const vec2 *ap, double ar, const CollPoly *bt, const vec2 *bp, vec2 crash[2])
Checks to see if a circle collides with a polygon.
int CollideSpritePolygon(const CollPoly *at, const vec2 *ap, const glTexture *bt, const int bsx, const int bsy, const vec2 *bp, vec2 *crash)
Checks whether or not a sprite collides with a polygon.
int CollidePolygon(const CollPoly *at, const vec2 *ap, const CollPoly *bt, const vec2 *bp, vec2 *crash)
Checks whether or not two polygons collide. /!\ The function is not symmetric: the points of polygon ...
double CollideCircleIntersection(const vec2 *p1, double r1, const vec2 *p2, double r2)
Calculates the area of intersection between two circles.
Header file with generic functions and naev-specifics.
int gl_isTrans(const glTexture *t, const int x, const int y)
Checks to see if a pixel is transparent in a texture.
Represents a polygon used for collision detection.
Abstraction for rendering sprite sheets.