need to identify bug in the line vs triangle/rectangle collision routines
This commit is contained in:
parent
c9f5807205
commit
642c2e9877
24
src/main.cpp
24
src/main.cpp
|
@ -246,7 +246,9 @@ static void update( float dt )
|
|||
if(MyBoss->Test_Impact(MyPlayer->Lasers[u])==true)
|
||||
{
|
||||
//TODO : we can create a list of impacts here, to be rendered later on
|
||||
Create_Impact( (int) MyBoss->x, (int) MyBoss->y );
|
||||
|
||||
//Create_Impact( (int) MyBoss->x, (int) MyBoss->y );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,18 +334,18 @@ static void render( void )
|
|||
}
|
||||
|
||||
#if(BIAS)
|
||||
if (texttodraw>=1) Azur_draw_text_shmup(1,01, "FPS = %.0f", (float) (1000000.0f / elapsedTime) );
|
||||
//if (texttodraw>=1) Azur_draw_text(1,11, "Part.= %d - Bull.= %d", MyParticles.size(), MyPlayerBullets.size() );
|
||||
//if (texttodraw>=1 && !MyEnemies.empty()) Azur_draw_text(1,21, "Ennmy Life= %d", MyEnemies[0]->life );
|
||||
|
||||
if (texttodraw>=2) Azur_draw_text_shmup(1,30, "Update = %.3f ms", (float) time_update / 1000.0f );
|
||||
if (texttodraw>=2) Azur_draw_text_shmup(1,45, "Render = %.3f ms", (float) time_render / 1000.0f );
|
||||
if (texttodraw>=2) Azur_draw_text_shmup(1,60, ">Total = %.0f ms", (float) elapsedTime / 1000.0f );
|
||||
if (texttodraw>=1) Azur_draw_text_shmup(0, 0, "FPS = %.0f", (float) (1000000.0f / elapsedTime) );
|
||||
if (texttodraw>=1) Azur_draw_text_shmup(0, 15, "LAZ = %d", MyPlayer->Lasers.size() );
|
||||
if (texttodraw>=1) Azur_draw_text_shmup(0, 30, "Part.= %d - Bull.= %d", MyParticles.size(), MyPlayerBullets.size() );
|
||||
|
||||
if (texttodraw>=2) Azur_draw_text_shmup(0,45, "Update = %.3f ms", (float) time_update / 1000.0f );
|
||||
if (texttodraw>=2) Azur_draw_text_shmup(0,60, "Render = %.3f ms", (float) time_render / 1000.0f );
|
||||
if (texttodraw>=2) Azur_draw_text_shmup(0,75, ">Total = %.0f ms", (float) elapsedTime / 1000.0f );
|
||||
|
||||
#if(MORE_RAM)
|
||||
if (texttodraw>=3) Azur_draw_text_shmup(1,75, "Mem Used : %d", _uram_stats->used_memory + extram_stats->used_memory);
|
||||
if (texttodraw>=3) Azur_draw_text_shmup(1,90, "Mem Free : %d", _uram_stats->free_memory + extram_stats->free_memory);
|
||||
if (texttodraw>=3) Azur_draw_text_shmup(1,105, "Mem Peak Used : %d", _uram_stats->peak_used_memory + extram_stats->peak_used_memory );
|
||||
if (texttodraw>=3) Azur_draw_text_shmup(0,90, "Mem Used : %d", _uram_stats->used_memory + extram_stats->used_memory);
|
||||
if (texttodraw>=3) Azur_draw_text_shmup(0,105, "Mem Free : %d", _uram_stats->free_memory + extram_stats->free_memory);
|
||||
if (texttodraw>=3) Azur_draw_text_shmup(0,120, "Mem Peak Used : %d", _uram_stats->peak_used_memory + extram_stats->peak_used_memory );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -413,18 +413,19 @@ bool Boss::Test_Impact( Laser *projectile )
|
|||
|
||||
bool hit = false;
|
||||
|
||||
/* We check if the bullet collides with teh shield of the boss */
|
||||
/* We check if the laser collides with the shield of the boss */
|
||||
for( int i=0; i< NB_PIECES_BOSS; i++ )
|
||||
{
|
||||
if (Pieces[i*2].toberemoved == false)
|
||||
{
|
||||
Vector2D A((int) XdataBossExternal[ Pieces[i*2].P1 ], (int) YdataBossExternal[ Pieces[i*2].P1 ]);
|
||||
Vector2D B((int) XdataBossExternal[ Pieces[i*2].P2 ], (int) YdataBossExternal[ Pieces[i*2].P2 ]);
|
||||
Vector2D C((int) XdataBossInternal[ Pieces[i*2].P3 ], (int) YdataBossInternal[ Pieces[i*2].P3 ]);
|
||||
Vector2D A( XdataBossExternal[ Pieces[i*2].P1 ], YdataBossExternal[ Pieces[i*2].P1 ]);
|
||||
Vector2D B( XdataBossExternal[ Pieces[i*2].P2 ], YdataBossExternal[ Pieces[i*2].P2 ]);
|
||||
Vector2D C( XdataBossInternal[ Pieces[i*2].P3 ], YdataBossInternal[ Pieces[i*2].P3 ]);
|
||||
|
||||
if (LineTriangle_Collision( Start, Direction, A, B, C))
|
||||
{
|
||||
Pieces[i*2].life -= projectile->strength;
|
||||
Create_Impact(((int) (A.x + B.x + C.x))/3, ((int) (A.y + B.y + C.y))/3 );
|
||||
if (Pieces[i*2].life<=0)
|
||||
{
|
||||
Pieces[i*2].toberemoved = true;
|
||||
|
@ -437,13 +438,14 @@ bool Boss::Test_Impact( Laser *projectile )
|
|||
|
||||
if (Pieces[i*2+1].toberemoved == false)
|
||||
{
|
||||
Vector2D A((int) XdataBossInternal[ Pieces[i*2+1].P1 ], (int) YdataBossInternal[ Pieces[i*2+1].P1 ]);
|
||||
Vector2D B((int) XdataBossInternal[ Pieces[i*2+1].P2 ], (int) YdataBossInternal[ Pieces[i*2+1].P2 ]);
|
||||
Vector2D C((int) XdataBossExternal[ Pieces[i*2+1].P3 ], (int) YdataBossExternal[ Pieces[i*2+1].P3 ]);
|
||||
Vector2D A( XdataBossInternal[ Pieces[i*2+1].P1 ], YdataBossInternal[ Pieces[i*2+1].P1 ]);
|
||||
Vector2D B( XdataBossInternal[ Pieces[i*2+1].P2 ], YdataBossInternal[ Pieces[i*2+1].P2 ]);
|
||||
Vector2D C( XdataBossExternal[ Pieces[i*2+1].P3 ], YdataBossExternal[ Pieces[i*2+1].P3 ]);
|
||||
|
||||
if (LineTriangle_Collision( Start, Direction, A, B, C))
|
||||
{
|
||||
Pieces[i*2+1].life -= projectile->strength;
|
||||
Create_Impact(((int) (A.x + B.x + C.x))/3, ((int) (A.y + B.y + C.y))/3 );
|
||||
if (Pieces[i*2+1].life<=0)
|
||||
{
|
||||
Pieces[i*2+1].toberemoved = true;
|
||||
|
@ -454,17 +456,19 @@ bool Boss::Test_Impact( Laser *projectile )
|
|||
}
|
||||
}
|
||||
|
||||
/* We check if the bullet collides with the cannons of the boss */
|
||||
|
||||
/* We check if the laser collides with the cannons of the boss */
|
||||
for( int i=0; i<NB_GUNS; i++ )
|
||||
{
|
||||
if (Guns[i].toberemoved == false)
|
||||
{
|
||||
Vector2D BoxMin((int) xGuns[i] - img_BossGun.width/2, (int) yGuns[i] - img_BossGun.height/2);
|
||||
Vector2D BoxMax((int) xGuns[i] + img_BossGun.width/2, (int) yGuns[i] + img_BossGun.height/2);
|
||||
Vector2D BoxMin( xGuns[i] - libnum::num(img_BossGun.width/2), yGuns[i] - libnum::num(img_BossGun.height/2) );
|
||||
Vector2D BoxMax( xGuns[i] + libnum::num(img_BossGun.width/2), yGuns[i] + libnum::num(img_BossGun.height/2) );
|
||||
|
||||
if (LineRectangle_Collision( Start, Direction, BoxMin, BoxMax ))
|
||||
{
|
||||
Guns[i].life -= projectile->strength;
|
||||
Create_Impact( (int) xGuns[i], (int) yGuns[i] );
|
||||
if (Guns[i].life<0)
|
||||
{
|
||||
Guns[i].toberemoved = true;
|
||||
|
@ -474,18 +478,20 @@ bool Boss::Test_Impact( Laser *projectile )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* We check if the bullet collides with the main ship part of the boss */
|
||||
Vector2D BoxMin(xmin, ymin);
|
||||
Vector2D BoxMax(xmax, ymax);
|
||||
/* We check if the laser collides with the main ship part of the boss */
|
||||
Vector2D BoxMin( libnum::num(this->xmin), libnum::num(this->ymin) );
|
||||
Vector2D BoxMax( libnum::num(this->xmax), libnum::num(this->ymax) );
|
||||
|
||||
if (LineRectangle_Collision( Start, Direction, BoxMin, BoxMax ))
|
||||
{
|
||||
life -= projectile->strength;
|
||||
Create_Impact( (int) x, (int) y );
|
||||
if (life<0)
|
||||
{
|
||||
this->toberemoved = true;
|
||||
Create_Explosion( (int) x, (int) y );
|
||||
Create_Explosion( (int) this->x, (int) this->y );
|
||||
}
|
||||
hit = true;
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ void Laser::Update( float dt )
|
|||
void Laser::Render( void )
|
||||
{
|
||||
// TODO this is juste for quick implementation : a thick Line Shader will be needed to be able to plot lasers in every directions
|
||||
azrp_line((int) sx , (int) sy , (int) (sx+dx*400) , (int) (sy+dy*400) , C_WHITE );
|
||||
azrp_line((int) sx-1, (int) sy-1, (int) (sx+dx*400)-1, (int) (sy+dy*400)-1, C_WHITE );
|
||||
azrp_line((int) sx-2, (int) sy-2, (int) (sx+dx*400)-2, (int) (sy+dy*400)-2, RGB565_AZURBLUE );
|
||||
azrp_line((int) sx+1, (int) sy+1, (int) (sx+dx*400)+1, (int) (sy+dy*400)+1, C_WHITE );
|
||||
azrp_line((int) sx+2, (int) sy+2, (int) (sx+dx*400)+2, (int) (sy+dy*400)+2, RGB565_AZURBLUE );
|
||||
azrp_line((int) sx , (int) sy , (int) (sx+dx*1000) , (int) (sy+dy*1000) , C_WHITE );
|
||||
azrp_line((int) sx-1, (int) sy-1, (int) (sx+dx*1000)-1, (int) (sy+dy*1000)-1, RGB565_OCEANBLUE );
|
||||
azrp_line((int) sx-2, (int) sy-2, (int) (sx+dx*1000)-2, (int) (sy+dy*1000)-2, RGB565_AZURBLUE );
|
||||
azrp_line((int) sx+1, (int) sy+1, (int) (sx+dx*1000)+1, (int) (sy+dy*1000)+1, RGB565_OCEANBLUE );
|
||||
azrp_line((int) sx+2, (int) sy+2, (int) (sx+dx*1000)+2, (int) (sy+dy*1000)+2, RGB565_AZURBLUE );
|
||||
}
|
|
@ -270,7 +270,16 @@ void Player::Activate_Laser( void )
|
|||
isLaser = true;
|
||||
Laser *mylaser1 = new Laser( (int) xmax, (int) y, 1, 0, LASER );
|
||||
Lasers.push_back( mylaser1 );
|
||||
|
||||
/*
|
||||
Laser *mylaser2 = new Laser( (int) xmax, (int) y, 0, -1, LASER );
|
||||
Lasers.push_back( mylaser2 );
|
||||
|
||||
Laser *mylaser3 = new Laser( (int) xmax, (int) y, 0, 1, LASER );
|
||||
Lasers.push_back( mylaser3 );
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Player::Desactivate_Laser( void )
|
||||
|
|
|
@ -222,45 +222,33 @@ bool Pixel_Perfect_Collision( SpriteLocator image1, SpriteLocator image2 )
|
|||
}
|
||||
|
||||
|
||||
/* NEW IMPLEMENTATION - TO TEST */
|
||||
|
||||
/* COHEN-SUTHERLAND Line/Rectangle intersection*/
|
||||
|
||||
typedef uint8_t OutCode;
|
||||
const uint8_t INSIDE = 0; // 0000
|
||||
const uint8_t LEFT = 1; // 0001
|
||||
const uint8_t RIGHT = 2; // 0010
|
||||
const uint8_t BOTTOM = 4; // 0100
|
||||
const uint8_t TOP = 8; // 1000
|
||||
|
||||
OutCode ComputeOutCode( Vector2D Point, Vector2D Min, Vector2D Max )
|
||||
bool get_line_intersection( Vector2D p0, Vector2D p1, Vector2D p2, Vector2D p3, Vector2D *pr)
|
||||
{
|
||||
OutCode code = INSIDE; // initialised as being inside of clip window
|
||||
if (Point.x < Min.x) // to the left of clip window
|
||||
code |= LEFT;
|
||||
else if (Point.x > Max.x) // to the right of clip window
|
||||
code |= RIGHT;
|
||||
if (Point.y < Min.y) // below the clip window
|
||||
code |= BOTTOM;
|
||||
else if (Point.y > Max.y) // above the clip window
|
||||
code |= TOP;
|
||||
return code;
|
||||
Vector2D s1, s2;
|
||||
s1 = p1 - p0; s1 = p1 - p0;
|
||||
s2 = p3 - p2; s2 = p3 - p2;
|
||||
|
||||
libnum::num s, t;
|
||||
s = (-s1.y * (p0.x - p2.x) + s1.x * (p0.y - p2.y)) / (-s2.x * s1.y + s1.x * s2.y);
|
||||
t = ( s2.x * (p0.y - p2.y) - s2.y * (p0.x - p2.x)) / (-s2.x * s1.y + s1.x * s2.y);
|
||||
|
||||
if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
|
||||
{
|
||||
// Collision detected
|
||||
if (pr != NULL)
|
||||
{
|
||||
(*pr).x = p0.x + (t * s1.x);
|
||||
(*pr).y = p0.y + (t * s1.y);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // No collision
|
||||
}
|
||||
|
||||
|
||||
bool LineRectangle_Collision( Vector2D Start, Vector2D Direction, Vector2D Min, Vector2D Max )
|
||||
{
|
||||
Vector2D End = Start.Clone();
|
||||
End.Add( Direction, libnum::num(1000));
|
||||
|
||||
OutCode outcode0 = ComputeOutCode( Start, Min, Max );
|
||||
OutCode outcode1 = ComputeOutCode( End, Min, Max );
|
||||
bool accept = false;
|
||||
|
||||
|
||||
if (!(outcode0 | outcode1)) return true; // both point inside so it hits
|
||||
else if (outcode0 & outcode1) return false; // both point on the same sides outoff the rectangle --> no hit possible
|
||||
else return true; // cross at least on one segment
|
||||
}
|
||||
/* FIRST IMPLEMENTATION USING THE VECTOR2D.H CLASS */
|
||||
|
||||
/* O is the origin, dir is the direction of the half line, A and B are the locations of the segment ends*/
|
||||
bool LineSegment_Collision( Vector2D O, Vector2D dir, Vector2D A, Vector2D B )
|
||||
|
@ -268,7 +256,7 @@ bool LineSegment_Collision( Vector2D O, Vector2D dir, Vector2D A, Vector2D B )
|
|||
|
||||
Vector2D OA = A - O;
|
||||
|
||||
/* create the point P corresponding to the "end" of the infinite side of the hald line */
|
||||
/* create the point P corresponding to the "end" of the infinite side of the half line */
|
||||
/* line length chosen to 1000 units as is it bigger than the diagonal of the screen in pixels*/
|
||||
Vector2D P = O.Clone();
|
||||
P.Add(dir, libnum::num(1000));
|
||||
|
@ -291,12 +279,31 @@ bool LineSegment_Collision( Vector2D O, Vector2D dir, Vector2D A, Vector2D B )
|
|||
}
|
||||
|
||||
|
||||
|
||||
bool LineRectangle_Collision( Vector2D Start, Vector2D Direction, Vector2D Min, Vector2D Max )
|
||||
{
|
||||
Vector2D End = Start.Clone();
|
||||
End.Add( Direction, libnum::num(1000));
|
||||
|
||||
Vector2D P1(Min.x, Min.y);
|
||||
Vector2D P2(Max.x, Min.y);
|
||||
Vector2D P3(Max.x, Max.y);
|
||||
Vector2D P4(Min.x, Max.y);
|
||||
|
||||
return( get_line_intersection(Start, End, P1, P2, NULL)
|
||||
|| get_line_intersection(Start, End, P2, P3, NULL)
|
||||
|| get_line_intersection(Start, End, P3, P4, NULL)
|
||||
|| get_line_intersection(Start, End, P4, P1, NULL));
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool LineTriangle_Collision( Vector2D Start, Vector2D Direction, Vector2D A, Vector2D B, Vector2D C )
|
||||
{
|
||||
if ( LineSegment_Collision( Start, Direction, A, B)
|
||||
|| LineSegment_Collision( Start, Direction, A, C)
|
||||
|| LineSegment_Collision( Start, Direction, B, C))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
Vector2D End = Start.Clone();
|
||||
End.Add( Direction, libnum::num(1000));
|
||||
|
||||
return( get_line_intersection(Start, End, A, B, NULL)
|
||||
|| get_line_intersection(Start, End, B, C, NULL)
|
||||
|| get_line_intersection(Start, End, C, A, NULL));
|
||||
}
|
Loading…
Reference in New Issue