[Add] Some untested collision detection routines.
This commit is contained in:
parent
b31fda7ce8
commit
9f8b1be682
121
src/collision.c
121
src/collision.c
@ -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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user