24 float x1,
float y1,
float x2,
float y2,
vec2* crash );
34 xmlNodePtr cur = node->children;
36 if (xml_isNode(cur,
"x")) {
37 char *list = xml_get(cur);
40 char *ch = strtok(list,
",");
41 polygon->
x = malloc(
sizeof(
float) );
47 polygon->
x = realloc( polygon->
x,
sizeof(
float) * i );
52 ch = strtok(NULL,
",");
55 else if (xml_isNode(cur,
"y")) {
56 char *list = xml_get(cur);
59 char *ch = strtok(list,
",");
60 polygon->
y = malloc(
sizeof(
float) );
66 polygon->
y = realloc( polygon->
y,
sizeof(
float) * i );
71 ch = strtok(NULL,
",");
75 }
while (xml_nextNode(cur));
98 const glTexture* bt,
const int bsx,
const int bsy,
const vec2* bp,
102 int ax1,ax2, ay1,ay2;
103 int bx1,bx2, by1,by2;
104 int inter_x0, inter_x1, inter_y0, inter_y1;
106 int abx,aby, bbx, bby;
110 if (at->
trans == NULL) {
111 WARN(_(
"Texture '%s' has no transparency map"), at->
name);
114 if (bt->
trans == NULL) {
115 WARN(_(
"Texture '%s' has no transparency map"), bt->
name);
121 ax1 = (int)VX(*ap) - (int)(at->
sw)/2;
122 ay1 = (int)VY(*ap) - (int)(at->
sh)/2;
123 ax2 = ax1 + (int)(at->
sw) - 1;
124 ay2 = ay1 + (int)(at->
sh) - 1;
127 bx1 = (int)VX(*bp) - (int)(bt->
sw)/2;
128 by1 = (int)VY(*bp) - (int)(bt->
sh)/2;
129 bx2 = bx1 + bt->
sw - 1;
130 by2 = by1 + bt->
sh - 1;
133 if ((bx2 < ax1) || (ax2 < bx1))
return 0;
134 if ((by2 < ay1) || (ay2 < by1))
return 0;
137 inter_x0 =
MAX( ax1, bx1 );
138 inter_x1 =
MIN( ax2, bx2 );
139 inter_y0 =
MAX( ay1, by1 );
140 inter_y1 =
MIN( ay2, by2 );
143 rasy = at->
sy - asy - 1;
144 rbsy = bt->
sy - bsy - 1;
147 abx = asx*(int)(at->
sw) - ax1;
148 aby = rasy*(int)(at->
sh) - ay1;
149 bbx = bsx*(int)(bt->
sw) - bx1;
150 bby = rbsy*(int)(bt->
sh) - by1;
152 for (y=inter_y0; y<=inter_y1; y++)
153 for (x=inter_x0; x<=inter_x1; x++)
180 const glTexture* bt,
const int bsx,
const int bsy,
const vec2* bp,
184 int ax1,ax2, ay1,ay2;
185 int bx1,bx2, by1,by2;
186 int inter_x0, inter_x1, inter_y0, inter_y1;
192 if (bt->
trans == NULL) {
193 WARN(_(
"Texture '%s' has no transparency map"), bt->
name);
199 ax1 = (int)VX(*ap) + (int)(at->
xmin);
200 ay1 = (int)VY(*ap) + (int)(at->
ymin);
201 ax2 = (int)VX(*ap) + (int)(at->
xmax);
202 ay2 = (int)VY(*ap) + (int)(at->
ymax);
205 bx1 = (int)VX(*bp) - (int)(bt->
sw)/2;
206 by1 = (int)VY(*bp) - (int)(bt->
sh)/2;
207 bx2 = bx1 + bt->
sw - 1;
208 by2 = by1 + bt->
sh - 1;
211 if ((bx2 < ax1) || (ax2 < bx1))
return 0;
212 if ((by2 < ay1) || (ay2 < by1))
return 0;
215 inter_x0 =
MAX( ax1, bx1 );
216 inter_x1 =
MIN( ax2, bx2 );
217 inter_y0 =
MAX( ay1, by1 );
218 inter_y1 =
MIN( ay2, by2 );
221 rbsy = bt->
sy - bsy - 1;
224 bbx = bsx*(int)(bt->
sw) - bx1;
225 bby = rbsy*(int)(bt->
sh) - by1;
226 for (y=inter_y0; y<=inter_y1; y++) {
227 for (x=inter_x0; x<=inter_x1; x++) {
257 int ax1,ax2, ay1,ay2;
258 int bx1,bx2, by1,by2;
259 int inter_x0, inter_x1, inter_y0, inter_y1;
260 float xabs, yabs, x1, y1, x2, y2;
263 ax1 = (int)VX(*ap) + (int)(at->
xmin);
264 ay1 = (int)VY(*ap) + (int)(at->
ymin);
265 ax2 = (int)VX(*ap) + (int)(at->
xmax);
266 ay2 = (int)VY(*ap) + (int)(at->
ymax);
269 bx1 = (int)VX(*bp) + (int)(bt->
xmin);
270 by1 = (int)VY(*bp) + (int)(bt->
ymin);
271 bx2 = (int)VX(*bp) + (int)(bt->
xmax);
272 by2 = (int)VY(*bp) + (int)(bt->
ymax);
275 if ((bx2 < ax1) || (ax2 < bx1))
return 0;
276 if ((by2 < ay1) || (ay2 < by1))
return 0;
279 inter_x0 =
MAX( ax1, bx1 );
280 inter_x1 =
MIN( ax2, bx2 );
281 inter_y0 =
MAX( ay1, by1 );
282 inter_y1 =
MIN( ay2, by2 );
285 for (
int i=0; i<=bt->
npt-1; i++) {
286 xabs = bt->
x[i] + VX(*bp);
287 yabs = bt->
y[i] + VY(*bp);
289 if ((xabs<inter_x0) || (xabs>inter_x1) ||
290 (yabs<inter_y0) || (yabs>inter_y1)) {
292 crash->
x = (int)xabs;
293 crash->
y = (int)yabs;
300 x1 = bt->
x[0] + VX(*bp);
301 y1 = bt->
y[0] + VY(*bp);
302 x2 = bt->
x[bt->
npt-1] + VX(*bp);
303 y2 = bt->
y[bt->
npt-1] + VY(*bp);
306 for (
int i=0; i<=bt->
npt-2; i++) {
307 x1 = bt->
x[i] + VX(*bp);
308 y1 = bt->
y[i] + VY(*bp);
309 x2 = bt->
x[i+1] + VX(*bp);
310 y2 = bt->
y[i+1] + VY(*bp);
329 rpolygon->
npt = ipolygon->
npt;
330 rpolygon->
x = malloc( ipolygon->
npt*
sizeof(
float) );
331 rpolygon->
y = malloc( ipolygon->
npt*
sizeof(
float) );
340 for (
int i=0; i<=rpolygon->
npt-1; i++) {
341 d = ipolygon->
x[i] * ct - ipolygon->
y[i] *
st;
346 d = ipolygon->
x[i] *
st + ipolygon->
y[i] * ct ;
365 float vprod, sprod, angle;
366 float dxi, dxip, dyi, dyip;
373 for (
int i=0; i<=at->
npt-2; i++) {
374 dxi = at->
x[i] +VX(*ap)-x;
375 dxip = at->
x[i+1]+VX(*ap)-x;
376 dyi = at->
y[i] +VY(*ap)-y;
377 dyip = at->
y[i+1]+VY(*ap)-y;
378 sprod = dxi * dxip + dyi * dyip;
379 vprod = dxi * dyip - dyi * dxip;
380 angle += atan2(vprod, sprod);
382 dxi = at->
x[at->
npt-1] + VX(*ap) - x;
383 dxip = at->
x[0] + VX(*ap) - x;
384 dyi = at->
y[at->
npt-1] + VY(*ap)- y;
385 dyip = at->
y[0] + VY(*ap) - y;
386 sprod = dxi * dxip + dyi * dyip;
387 vprod = dxi * dyip - dyi * dxip;
388 angle += atan2(vprod, sprod);
390 if (
FABS(angle) < 1e-5)
409 float x1,
float y1,
float x2,
float y2,
vec2* crash )
411 float xi, xip, yi, yip;
415 xi = at->
x[at->
npt-1] + ap->
x;
416 xip = at->
x[0] + ap->
x;
417 yi = at->
y[at->
npt-1] + ap->
y;
418 yip = at->
y[0] + ap->
y;
421 for (
int i=0; i<=at->
npt-2; i++) {
422 xi = at->
x[i] + ap->
x;
423 xip = at->
x[i+1] + ap->
x;
424 yi = at->
y[i] + ap->
y;
425 yip = at->
y[i+1] + ap->
y;
449 double s2x,
double s2y,
double e2x,
double e2y,
vec2* crash )
451 double ua_t, ub_t, u_b;
454 ua_t = (e2x - s2x) * (s1y - s2y) - (e2y - s2y) * (s1x - s2x);
455 ub_t = (e1x - s1x) * (s1y - s2y) - (e1y - s1y) * (s1x - s2x);
456 u_b = (e2y - s2y) * (e1x - s1x) - (e2x - s2x) * (e1y - s1y);
463 if ((0. <= ua) && (ua <= 1.) && (0. <= ub) && (ub <= 1.)) {
464 crash->
x = s1x + ua * (e1x - s1x);
465 crash->
y = s1y + ua * (e1y - s1y);
474 if ((ua_t == 0.) || (ub_t == 0.))
502 const glTexture* bt,
const int bsx,
const int bsy,
const vec2* bp,
505 int x,y, rbsy, bbx,bby;
506 double ep[2], bl[2], tr[2], v[2], mod;
508 vec2 tmp_crash, border[2];
511 if (bt->
trans == NULL) {
512 WARN(_(
"Texture '%s' has no transparency map"), bt->
name);
517 ep[0] = ap->
x + al*cos(ad);
518 ep[1] = ap->
y + al*sin(ad);
521 tr[0] = bp->
x + bt->
sw/2.;
522 tr[1] = bp->
y + bt->
sh/2.;
524 bl[0] = bp->
x - bt->
sw/2.;
525 bl[1] = bp->
y - bt->
sh/2.;
533 bl[0], bl[1], bl[0], tr[1], &tmp_crash) == 1) {
534 border[hits].x = tmp_crash.
x;
535 border[hits].y = tmp_crash.
y;
540 bl[0], tr[1], tr[0], tr[1], &tmp_crash) == 1) {
541 border[hits].x = tmp_crash.
x;
542 border[hits].y = tmp_crash.
y;
548 tr[0], tr[1], tr[0], bl[1], &tmp_crash) == 1) {
549 border[hits].x = tmp_crash.
x;
550 border[hits].y = tmp_crash.
y;
555 tr[0], bl[1], bl[0], bl[1], &tmp_crash) == 1) {
556 border[hits].x = tmp_crash.
x;
557 border[hits].y = tmp_crash.
y;
576 v[0] = border[1].x - border[0].x;
577 v[1] = border[1].y - border[0].y;
579 mod = MOD(v[0],v[1])/2.;
584 rbsy = bt->
sy - bsy - 1;
586 bbx = bsx*(int)(bt->
sw);
587 bby = rbsy*(int)(bt->
sh);
590 x = border[0].x - bl[0] + v[0];
591 y = border[0].y - bl[1] + v[1];
592 while ((x > 0.) && (x < bt->sw) && (y > 0.) && (y < bt->sh)) {
594 if (!
gl_isTrans(bt, bbx+(
int)x, bby+(
int)y)) {
595 crash[real_hits].
x = x + bl[0];
596 crash[real_hits].
y = y + bl[1];
605 x = border[1].x - bl[0] - v[0];
606 y = border[1].y - bl[1] - v[1];
607 while ((x > 0.) && (x < bt->sw) && (y > 0.) && (y < bt->sh)) {
609 if (!
gl_isTrans(bt, bbx+(
int)x, bby+(
int)y)) {
610 crash[real_hits].
x = x + bl[0];
611 crash[real_hits].
y = y + bl[1];
625 if (real_hits == 1) {
626 crash[1].
x = crash[0].
x;
627 crash[1].
y = crash[0].
y;
653 double ep[2], bl[2], tr[2];
654 double xi, yi, xip, yip;
659 ep[0] = ap->
x + al*cos(ad);
660 ep[1] = ap->
y + al*sin(ad);
663 vectnull( &tmp_crash );
667 crash[real_hits].
x = ap->
x;
668 crash[real_hits].
y = ap->
y;
674 crash[real_hits].
x = ep[0];
675 crash[real_hits].
y = ep[1];
684 if (real_hits == 0) {
686 tr[0] = bp->
x + (double)bt->
xmax;
687 tr[1] = bp->
y + (
double)bt->
ymax;
689 bl[0] = bp->
x + (double)bt->
xmin;
690 bl[1] = bp->
y + (
double)bt->
ymin;
698 bl[0], bl[1], bl[0], tr[1], &tmp_crash) == 1)
703 bl[0], tr[1], tr[0], tr[1], &tmp_crash) == 1)
708 tr[0], tr[1], tr[0], bl[1], &tmp_crash) == 1)
713 tr[0], bl[1], bl[0], bl[1], &tmp_crash) == 1)
724 xi = (double)bt->
x[bt->
npt-1] + bp->
x;
725 xip = (
double)bt->
x[0] + bp->
x;
726 yi = (double)bt->
y[bt->
npt-1] + bp->
y;
727 yip = (
double)bt->
y[0] + bp->
y;
729 xi, yi, xip, yip, &tmp_crash) ) {
730 crash[real_hits].
x = tmp_crash.
x;
731 crash[real_hits].
y = tmp_crash.
y;
736 for (
int i=0; i<=bt->
npt-2; i++) {
737 xi = (double)bt->
x[i] + bp->
x;
738 xip = (
double)bt->
x[i+1] + bp->
x;
739 yi = (double)bt->
y[i] + bp->
y;
740 yip = (
double)bt->
y[i+1] + bp->
y;
742 xi, yi, xip, yip, &tmp_crash) ) {
743 crash[real_hits].
x = tmp_crash.
x;
744 crash[real_hits].
y = tmp_crash.
y;
757 if (real_hits == 1) {
758 crash[1].
x = crash[0].
x;
759 crash[1].
y = crash[0].
y;
766static int linePointOnSegment(
double d1,
double x1,
double y1,
double x2,
double y2,
double x,
double y )
769 double d2 = hypot( x-x1, y-y1 );
770 double d3 = hypot( x2-x, y2-y );
771 return fabs(d1 - d2 - d3) < 1e-8;
774#define FX( A, B, C, x ) (-(A * x + C) / B)
775#define FY( A, B, C , y ) (-(B * y + C) / A)
787 const vec2 *cc,
double cr,
vec2 crash[2] )
798 double C = x2 * y1 - x1 * y2;
808 if (fabs(B) >= 1e-8) {
809 b = 2. * (A *
C + A * B * y0 -
pow2(B) * x0);
815 b = 2. * (B *
C + A * B * x0 -
pow2(A) * y0);
824 d1 = hypot( x2-x1, y2-y1 );
830 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
838 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
849 x = (-b +
d) / (2. * a);
851 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
856 x = (-b -
d) / (2. * a);
858 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
864 y = (-b +
d) / (2. * a);
866 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
871 y = (-b -
d) / (2. * a);
873 if (linePointOnSegment( d1, x1, y1, x2, y2, x, y )) {
887double CollideCircleIntersection(
const vec2 *p1,
double r1,
888 const vec2 *p2,
double r2 )
890 double dist2 = vec2_dist2( p1, p2 );
893 if (dist2 >
pow2(r1+r2))
897 if (dist2 <=
pow2(fabs(r1-r2)))
898 return M_PI *
pow2(
MIN(r1, r2) );
902 if ((dist2==0.) && (r1==r2))
903 return M_PI *
pow2(r1);
907 double dist = sqrt( dist2 );
908 double distc1 = (
pow2(r1) -
pow2(r2) + dist2) / (2. * dist);
909 double distc2 = dist - distc1;
910 double height = sqrt(
pow2(r1) -
pow2(distc1) );
912 double ang1 = fmod( atan2( height, distc1 ) * 2. + 2.*M_PI, 2.*M_PI );
913 double ang2 = fmod( atan2( height, distc2 ) * 2. + 2.*M_PI, 2.*M_PI );
915 double A1 =
pow2(r1) / 2.0 * (ang1 - sin(ang1));
916 double A2 =
pow2(r2) / 2.0 * (ang2 - sin(ang2));
void RotatePolygon(CollPoly *rpolygon, CollPoly *ipolygon, float theta)
Rotates 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.
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.
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.
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 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 ...
static int pointInPolygon(const CollPoly *at, const vec2 *ap, float x, float y)
Checks whether or not a point is inside a polygon.
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.