[Add] Some untested collision detection routines.

This commit is contained in:
Allanis 2013-09-15 22:34:11 +01:00
parent b31fda7ce8
commit 9f8b1be682
2 changed files with 124 additions and 8 deletions

View File

@ -84,6 +84,44 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
return 0;
}
/**
* @fn int CollideLineLine(double s1x, double s1y, double e1x, double e1y,
* double s2x, double s2y, double e2x, double e2y) {
*
* @brief Check to see if two lines collide.
* @param[in] s1 .......
*/
int CollideLineLine(double s1x, double s1y, double e1x, double e1y,
double s2x, double s2y, double e2x, double e2y, Vec2* crash) {
double ua_t, ub_t, u_b;
double ua, ub;
ua_t = (e2x - s2x) * (s1y - s2y) - (e2y - s2y) * (s1x - s2x);
ub_t = (e1x - s1x) * (s1y - s2y) - (e1y - s1y) * (s1x - s2x);
u_b = (e2y - s2y) * (e1x - s1x) - (e2x - s2x) * (e1y - s1y);
if(u_b != 0.) {
ua = ua_t / u_b;
ub = ub_t / u_b;
/* Intersection at a point. */
if((0. <= ua) && (ua <= 1.) && (0. <= ub) && (ub <= 1.)) {
crash->x = s1x + ua * (e1x - s1x);
crash->y = s1y + ua * (e1y - s1y);
return 1;
} else
return 0;
} else {
/* Coincidence. */
if((ua_t == 0.) || (ub_t == 0.))
return 3;
/* Parallel. */
else
return 2;
}
}
/**
* @fn int CollideLineSprite(const Vec2* ap, double dir,
* const glTexture* bt, const int bsx, const int bsy,
@ -99,16 +137,91 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
*
* @sa CollideSprite
*/
int CollideLineSprite(const Vec2* ap, double ad,
int CollideLineSprite(const Vec2* ap, double ad, double al,
const glTexture* bt, const int bsx, const int bsy, const Vec2* bp,
Vec2* crash) {
(void)ap;
(void)ad;
(void)bt;
(void)bsx;
(void)bsy;
(void)bp;
(void) bt;
(void) bsx;
(void) bsy;
double ep[2], tr[2], v[2], mod;
int hits;
Vec2 tmp_crash, border[2];
/* Set up end point of line. */
ep[0] = ap->x + al*cos(ad);
ep[1] = ap->y + al*sin(ad);
/* Set up top right corner of the rectangle. */
tr[0] = ap->x + al*cos(ad);
tr[1] = ap->y + al*sin(ad);
/* Start check for rectangular collision. */
hits = 0;
/* Left border. */
if(CollideLineLine(ap->x, ap->y, ep[0], ep[1],
bp->x, bp->y, bp->x, tr[1], &tmp_crash) != 0) {
border[hits].x = tmp_crash.x;
border[hits].y = tmp_crash.y;
hits++;
}
/* Top border. */
if(CollideLineLine(ap->x, ap->y, ep[0], ep[1],
bp->x, tr[1], tr[0], tr[1], &tmp_crash) != 0) {
border[hits].x = tmp_crash.x;
border[hits].y = tmp_crash.y;
hits++;
}
/* Now we are going to have to make sure hits isn't 2. */
/* Right border. */
if((hits < 2) && CollideLineLine(ap->x, ap->y, ep[0], ep[1],
tr[0], tr[1], tr[0], bp->y, &tmp_crash) != 0) {
border[hits].x = tmp_crash.x;
border[hits].y = tmp_crash.y;
hits++;
}
/* Bottom border. */
if((hits < 2) && CollideLineLine(ap->x, ap->y, ep[0], ep[1],
tr[0], bp->y, bp->x, bp->y, &tmp_crash) != 0) {
border[hits].x = tmp_crash.x;
border[hits].y = tmp_crash.y;
hits++;
}
/* No hits - missed. */
if(hits == 0)
return 0;
/* Special case only one hit - Shouldn't happen, but just in case. */
if(hits == 1) {
if(hits == 1) {
/* We just return the same point twise. */
crash[0].x = crash[1].x = border[0].x;
crash[0].y = crash[1].y = border[0].y;
}
return 1;
}
crash[0].x = border[0].x;
crash[0].y = border[0].y;
crash[1].x = border[1].x;
crash[1].y = border[1].y;
return 1;
/* @todo Now we do a pixel perfect approach. */
/* directional vector (normalised). */
v[0] = border[1].x - border[0].x;
v[1] = border[1].y - border[0].y;
/* Normalize. */
mod = 2*MOD(v[0], v[1]); /* Multiply by two to reduce check amount. */
v[0] /= mod;
v[1] /= mod;
/* We start checking first border until we find collision. */
tmp_crash.x = border[0].x;
tmp_crash.y = border[0].y;
}

View File

@ -8,7 +8,10 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
const int bsx, const int bsy, const Vec2* bp,
Vec2* crash);
int CollideLineSprite(const Vec2* ap, double dir,
int CollideLineLine(double s1x, double s1y, double e1x, double e1y,
double s2x, double s2y, double e2x, double e2y, Vec2* crash);
int CollideLineSrite(const Vec2* ap, double ad, double al,
const glTexture* bt, const int bsx, const int bsy, const Vec2* bp,
Vec2* crash);