[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; |   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, |  * @fn int CollideLineSprite(const Vec2* ap, double dir, | ||||||
|  *                           const glTexture* bt, const int bsx, const int bsy, |  *                           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 |  * @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, |     const glTexture* bt, const int bsx, const int bsy, const Vec2* bp, | ||||||
|     Vec2* crash) { |     Vec2* crash) { | ||||||
| 
 | 
 | ||||||
|   (void)ap; |  | ||||||
|   (void)ad; |  | ||||||
|   (void) bt; |   (void) bt; | ||||||
|   (void) bsx; |   (void) bsx; | ||||||
|   (void) bsy; |   (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, |                   const int bsx, const int bsy, const Vec2* bp, | ||||||
|                   Vec2* crash); |                   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, |     const glTexture* bt, const int bsx, const int bsy, const Vec2* bp, | ||||||
|     Vec2* crash); |     Vec2* crash); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Allanis
						Allanis