[Change] Improved accuracy of collision on explosions.
This commit is contained in:
parent
b88bba7bdb
commit
e9985fc8ca
123
src/collision.c
123
src/collision.c
@ -3,8 +3,16 @@
|
|||||||
#include "collision.h"
|
#include "collision.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Collide sprite at (asx, asy) in 'at' at pos 'ap' with sprite at (bsx,bsy)
|
*
|
||||||
* in 'bt' at 'bp'
|
* @fn 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)
|
||||||
|
*
|
||||||
|
* @brief Check whether or not sprites collide.
|
||||||
|
*
|
||||||
|
* This function does pixel perfect checks. If the collision actually accurs,
|
||||||
|
* crash is set to store the real position of the collision.
|
||||||
*
|
*
|
||||||
* @param[in] at - Texture a.
|
* @param[in] at - Texture a.
|
||||||
* @param[in] asx - Position of x of sprite a.
|
* @param[in] asx - Position of x of sprite a.
|
||||||
@ -14,11 +22,13 @@
|
|||||||
* @param[in] bsx - Position of x of sprite b.
|
* @param[in] bsx - Position of x of sprite b.
|
||||||
* @param[in] bsy - Position of y of sprite b.
|
* @param[in] bsy - Position of y of sprite b.
|
||||||
* @param[in] bp - Position in space of sprite b.
|
* @param[in] bp - Position in space of sprite b.
|
||||||
|
* @param[out] crash - Actual position of the collision (only on collision).
|
||||||
* @return 1 on collision, 0 else.
|
* @return 1 on collision, 0 else.
|
||||||
*/
|
*/
|
||||||
int CollideSprite(const glTexture* at, const int asx, const int asy,
|
int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||||
const Vec2* ap, const glTexture* bt,
|
const Vec2* ap, const glTexture* bt,
|
||||||
const int bsx, const int bsy, const Vec2* bp) {
|
const int bsx, const int bsy, const Vec2* bp,
|
||||||
|
Vec2* crash) {
|
||||||
|
|
||||||
int x,y;
|
int x,y;
|
||||||
int ax1, ax2, ay1, ay2;
|
int ax1, ax2, ay1, ay2;
|
||||||
@ -63,92 +73,43 @@ int CollideSprite(const glTexture* at, const int asx, const int asy,
|
|||||||
for(x = inter_x0; x <= inter_x1; x++)
|
for(x = inter_x0; x <= inter_x1; x++)
|
||||||
/* Compute offsets for surface before passing to TransparentPixel test. */
|
/* Compute offsets for surface before passing to TransparentPixel test. */
|
||||||
if((!gl_isTrans(at, abx + x, aby + y)) &&
|
if((!gl_isTrans(at, abx + x, aby + y)) &&
|
||||||
(!gl_isTrans(bt, bbx + x, bby + y)))
|
(!gl_isTrans(bt, bbx + x, bby + y))) {
|
||||||
|
|
||||||
|
/* Set the crash position. */
|
||||||
|
crash->x = x;
|
||||||
|
crash->y = y;
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculate collision path corrections.
|
* @fn int CollideLineSprite(const Vec2* ap, double dir,
|
||||||
|
* const glTexture* bt, const int bsx, const int bsy,
|
||||||
|
* const Vec2& bp, Vec2* crash)
|
||||||
*
|
*
|
||||||
* @param[in] p - Position of object that's trying to collide.
|
* @param[in] ap Origin of the line.
|
||||||
* @param[in] v - Velocity of object that's trying to collide.
|
* @param[in] ad Direction of the line.
|
||||||
* @param[in] tp - Position of the target to collide into.
|
* @param[in] bt Texture b.
|
||||||
* @param[in] tv - Velocity of the target to collide into.
|
* @param[in] bsx Position of x of sprite b.
|
||||||
* @param[in] limit - Accuracy limit.
|
* @param[in] bsy Position of y of sprite b
|
||||||
* @return Direction object will need to adjust velocity to for collision.
|
* @param[in] bp Position in space of sprite b.
|
||||||
|
* @return 1 on Collision, else 0.
|
||||||
|
*
|
||||||
|
* @sa CollideSprite
|
||||||
*/
|
*/
|
||||||
/*
|
int CollideLineSprite(const Vec2* ap, double ad,
|
||||||
* Doesn't work as expected, needs to be fixed to allow missiles to use
|
const glTexture* bt, const int bsx, const int bsy, const Vec2* bp,
|
||||||
* the physics engine instead of hacking their velocities.
|
Vec2* crash) {
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
double CollidePath(const Vec2* p, Vec2* v,
|
|
||||||
const Vec2* tp, Vec2* tv, double limit) {
|
|
||||||
|
|
||||||
double mx, my; /* Position modifiers. */
|
(void)ap;
|
||||||
double t, tt; /* Time to target. */
|
(void)ad;
|
||||||
Vec2 test, ttest; /* Test vector and target test vector. */
|
(void)bt;
|
||||||
double offset; /* Direction to face and error it produces. */
|
(void)bsx;
|
||||||
double mod, moddir; /* Modifier for iteration. */
|
(void)bsy;
|
||||||
int i;
|
(void)bp;
|
||||||
|
(void)crash;
|
||||||
|
|
||||||
/* Test vector. */
|
|
||||||
vect_cset(&test, tp->x - p->x, tp->y - p->y); /* Start byt straight line. */
|
|
||||||
t = VMOD(test) / VMOD(*v); /* d=v*t ==> t=d/v. */
|
|
||||||
|
|
||||||
/* Target test vector. */
|
|
||||||
vectnull(&ttest); /* Starting from itself. */
|
|
||||||
tt = VMOD(ttest) / VMOD(*tv);
|
|
||||||
|
|
||||||
/* Special case object isn't moving. */
|
|
||||||
if(VMOD(*v) < 1e-6)
|
|
||||||
return VANGLE(test);
|
|
||||||
|
|
||||||
/* Target faster than object. */
|
|
||||||
if(VMOD(*v) < VMOD(*tv)) {
|
|
||||||
vect_reflect(&test, v, tv);
|
|
||||||
return VANGLE(test);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop until error is minimal. */
|
|
||||||
offset = tt - t;
|
|
||||||
moddir = 1.; /* Start off by position increments. */
|
|
||||||
mod = 10.; /* Start off by a 10 second jump. */
|
|
||||||
i = 0;
|
|
||||||
while(FABS(offset) > limit) {
|
|
||||||
if(i > 100) break;
|
|
||||||
|
|
||||||
/* Calculate position modifiers. */
|
|
||||||
if(offset < -mod/2.) /* tt>t ==> major overshot. */
|
|
||||||
moddir = -1.;
|
|
||||||
else if(offset < 0.) { /* tt>t ==> overshot. */
|
|
||||||
/* Invert direction and half. */
|
|
||||||
moddir = -1.;
|
|
||||||
mod = mod/2.;
|
|
||||||
}
|
|
||||||
else if(offset > mod) /* tt<t ==> undershot. */
|
|
||||||
moddir = 1.; /* Make sure it's positive. */
|
|
||||||
else if(offset > 0.) { /* tt<t ==> minor undershot. */
|
|
||||||
/* Positive and shrink step. */
|
|
||||||
moddir = 1.;
|
|
||||||
mod = FABS(mod)/2.;
|
|
||||||
}
|
|
||||||
mx = tv->x * mod * moddir;
|
|
||||||
my = tv->y * mod * moddir;
|
|
||||||
|
|
||||||
/* Increment test vectors. */
|
|
||||||
vect_cadd(&test, mx, my);
|
|
||||||
vect_cadd(&ttest, mx, my);
|
|
||||||
|
|
||||||
/* Compare results. */
|
|
||||||
t = VMOD(test) / VMOD(*v);
|
|
||||||
tt = VMOD(ttest) / VMOD(*tv);
|
|
||||||
offset = tt - t;
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return VANGLE(test);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -5,9 +5,10 @@
|
|||||||
/* Return 1 if collision is detected. */
|
/* Return 1 if collision is detected. */
|
||||||
int CollideSprite(const glTexture* at, const int asx, const int asy,
|
int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||||
const Vec2* ap, const glTexture* bt,
|
const Vec2* ap, const glTexture* bt,
|
||||||
const int bsx, const int bsy, const Vec2* bp);
|
const int bsx, const int bsy, const Vec2* bp,
|
||||||
|
Vec2* crash);
|
||||||
|
|
||||||
/* Get direction to face the target. */
|
int CollideLineSprite(const Vec2* ap, double dir,
|
||||||
/*double CollidePath(const Vec2* p, Vec2* v,
|
const glTexture* bt, const int bsx, const int bsy, const Vec2* bp,
|
||||||
const Vec2* tp, Vec2* tv, const double limit);*/
|
Vec2* crash);
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ static void menu_main_exit(char* str) {
|
|||||||
/* Ze ingame menu. */
|
/* Ze ingame menu. */
|
||||||
/* Small ingame menu. */
|
/* Small ingame menu. */
|
||||||
void menu_small(void) {
|
void menu_small(void) {
|
||||||
if((player == NULL) player_isFlag(PLAYER_DESTROYED)
|
if((player == NULL) || player_isFlag(PLAYER_DESTROYED)
|
||||||
|| pilot_isFlag(player, PILOT_DEAD) ||
|
|| pilot_isFlag(player, PILOT_DEAD) ||
|
||||||
(menu_isOpen(MENU_MAIN) ||
|
(menu_isOpen(MENU_MAIN) ||
|
||||||
menu_isOpen(MENU_SMALL) ||
|
menu_isOpen(MENU_SMALL) ||
|
||||||
|
32
src/weapon.c
32
src/weapon.c
@ -68,7 +68,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir,
|
|||||||
static void weapon_render(const Weapon* w);
|
static void weapon_render(const Weapon* w);
|
||||||
static void weapons_updateLayer(const double dt, const WeaponLayer layer);
|
static void weapons_updateLayer(const double dt, const WeaponLayer layer);
|
||||||
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer);
|
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer);
|
||||||
static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer);
|
static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer, Vec2* pos);
|
||||||
static void weapon_destroy(Weapon* w, WeaponLayer layer);
|
static void weapon_destroy(Weapon* w, WeaponLayer layer);
|
||||||
static void weapon_free(Weapon* w);
|
static void weapon_free(Weapon* w);
|
||||||
/* Think. */
|
/* Think. */
|
||||||
@ -313,6 +313,7 @@ static void weapon_render(const Weapon* w) {
|
|||||||
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
||||||
int i, wsx, wsy, psx, psy;
|
int i, wsx, wsy, psx, psy;
|
||||||
glTexture* gfx;
|
glTexture* gfx;
|
||||||
|
Vec2 crash;
|
||||||
|
|
||||||
gfx = outfit_gfx(w->outfit);
|
gfx = outfit_gfx(w->outfit);
|
||||||
|
|
||||||
@ -329,16 +330,19 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
|||||||
/* Smart weapons only collide with their target. */
|
/* Smart weapons only collide with their target. */
|
||||||
if((weapon_isSmart(w)) && (pilot_stack[i]->id == w->target) &&
|
if((weapon_isSmart(w)) && (pilot_stack[i]->id == w->target) &&
|
||||||
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
||||||
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) {
|
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos,
|
||||||
weapon_hit(w, pilot_stack[i], layer);
|
&crash)) {
|
||||||
|
|
||||||
|
weapon_hit(w, pilot_stack[i], layer, &crash);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Dumb weapons hit anything not of the same faction. */
|
/* Dumb weapons hit anything not of the same faction. */
|
||||||
if(!weapon_isSmart(w) &&
|
if(!weapon_isSmart(w) &&
|
||||||
!areAllies(w->faction, pilot_stack[i]->faction) &&
|
!areAllies(w->faction, pilot_stack[i]->faction) &&
|
||||||
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
||||||
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos)) {
|
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos,
|
||||||
weapon_hit(w, pilot_stack[i], layer);
|
&crash)) {
|
||||||
|
weapon_hit(w, pilot_stack[i], layer, &crash);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,8 +353,16 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
|||||||
(*w->solid->update)(w->solid, dt);
|
(*w->solid->update)(w->solid, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Good shot. */
|
/**
|
||||||
static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
|
* fn static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer, vec2* pos)
|
||||||
|
*
|
||||||
|
* @breif Weapon hit the pilot.
|
||||||
|
* @param w Weapon Involved in the collision.
|
||||||
|
* @param p Pilot that got it.
|
||||||
|
* @param layer Layer to which the weapon belongs.
|
||||||
|
* @param pos Position of the hit.
|
||||||
|
*/
|
||||||
|
static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer, Vec2* pos) {
|
||||||
/* Someone should let the ai know it's been attacked. */
|
/* Someone should let the ai know it's been attacked. */
|
||||||
if(!pilot_isPlayer(p)) {
|
if(!pilot_isPlayer(p)) {
|
||||||
if((player_target == p->id) || (RNG(0,2) == 0)) { /* 33% chance. */
|
if((player_target == p->id) || (RNG(0,2) == 0)) { /* 33% chance. */
|
||||||
@ -361,12 +373,10 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
|
|||||||
}
|
}
|
||||||
ai_attacked(p, w->parent);
|
ai_attacked(p, w->parent);
|
||||||
}
|
}
|
||||||
spfx_add(outfit_spfx(w->outfit),
|
spfx_add(outfit_spfx(w->outfit), pos->x, pos->y,
|
||||||
VX(w->solid->pos), VY(w->solid->pos),
|
|
||||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
|
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
|
||||||
} else
|
} else
|
||||||
spfx_add(outfit_spfx(w->outfit),
|
spfx_add(outfit_spfx(w->outfit), pos->x, pos->y,
|
||||||
VX(w->solid->pos), VY(w->solid->pos),
|
|
||||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
|
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
|
||||||
|
|
||||||
/* Let the ship know that is should take some kind of damage. */
|
/* Let the ship know that is should take some kind of damage. */
|
||||||
|
Loading…
Reference in New Issue
Block a user