|
|
@ -11,7 +11,7 @@ using namespace olc; |
|
|
|
FaceBall* game; |
|
|
|
FaceBall* game; |
|
|
|
|
|
|
|
|
|
|
|
Enemy::Enemy(EnemyID id,vec3d pos,float rot,float radius) |
|
|
|
Enemy::Enemy(EnemyID id,vec3d pos,float rot,float radius) |
|
|
|
:id(id), health(game->enemyData[id].health), fireDelay(0), |
|
|
|
:id(id), health(game->enemyData[id].health), fireDelay(0), blinking(game->enemyData[id].blinking), |
|
|
|
Object({game->enemyData[id].mesh,pos,rot,radius}) {} |
|
|
|
Object({game->enemyData[id].mesh,pos,rot,radius}) {} |
|
|
|
|
|
|
|
|
|
|
|
EnemyID Enemy::GetID() { |
|
|
|
EnemyID Enemy::GetID() { |
|
|
@ -104,12 +104,31 @@ bool Enemy::isExploded() { |
|
|
|
return exploded; |
|
|
|
return exploded; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Enemy::Update(float fElapsedTime) { |
|
|
|
|
|
|
|
if (!isDead()) { |
|
|
|
|
|
|
|
aliveTime += fElapsedTime; |
|
|
|
|
|
|
|
if (isBlinking()) { |
|
|
|
|
|
|
|
blinkingAmt = std::sinf(30 * aliveTime); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Enemy::OnDeathEvent() { |
|
|
|
|
|
|
|
game->SubtractTag(); |
|
|
|
|
|
|
|
if (game->enemyData[id].powerupDrop != PowerupType::NONE) { |
|
|
|
|
|
|
|
game->SpawnPowerup(game->enemyData[id].powerupDrop, pos); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
blinkingAmt = 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void FaceBall::InitializeEnemyData() { |
|
|
|
void FaceBall::InitializeEnemyData() { |
|
|
|
enemyData[EnemyID::NONE] = { "VOID",undefined,BLACK }; |
|
|
|
enemyData[EnemyID::NONE] = { "VOID",undefined,BLACK }; |
|
|
|
enemyData[EXIT] = { "EXIT",undefined,GREEN }; |
|
|
|
enemyData[EXIT] = { "EXIT",undefined,GREEN }; |
|
|
|
enemyData[START] = { "SPAWN POSITION",undefined,{128,64,0} }; |
|
|
|
enemyData[START] = { "SPAWN POSITION",undefined,{128,64,0} }; |
|
|
|
enemyData[SHOOTME] = { "SHOOTME",enemy_ShootMe,YELLOW,1,1,PI / 8,2,1,0.2f,true }; |
|
|
|
enemyData[SHOOTME] = { "SHOOTME",enemy_ShootMe,YELLOW,1,1,PI / 8,2,1,0.2f,true }; |
|
|
|
enemyData[SHOOTME2] = { "SHOOTME2",enemy_IShoot,YELLOW,1,1,PI / 6,2,1,0.3f,true }; |
|
|
|
enemyData[SHOOTME2] = { "SHOOTME2",enemy_IShoot,YELLOW,1,1,PI / 6,2,1,0.3f,true }; |
|
|
|
|
|
|
|
enemyData[SHOOTME_ARMOR] = { "SHOOTME_ARMOR",enemy_ShootMe,YELLOW,6,1,PI / 6,2,1,0.3f,true,PowerupType::ARMOR,true }; |
|
|
|
enemyData[SONAR] = { "Sonar",enemy_Sonar,RED,5,1,PI / 8,2,1 }; |
|
|
|
enemyData[SONAR] = { "Sonar",enemy_Sonar,RED,5,1,PI / 8,2,1 }; |
|
|
|
enemyData[COIN] = { "Coin",undefined,BLUE }; |
|
|
|
enemyData[COIN] = { "Coin",undefined,BLUE }; |
|
|
|
enemyData[POWERUP_ARMOR] = { "Armor",undefined,{96,0,96} }; |
|
|
|
enemyData[POWERUP_ARMOR] = { "Armor",undefined,{96,0,96} }; |
|
|
@ -121,6 +140,32 @@ void FaceBall::InitializeEnemyData() { |
|
|
|
enemyData[AREA_MAP] = { "Map",undefined,GREEN }; |
|
|
|
enemyData[AREA_MAP] = { "Map",undefined,GREEN }; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FaceBall::InitializePowerupColors() { |
|
|
|
|
|
|
|
powerupColorData[PowerupType::ARMOR] = DARK_GREEN; |
|
|
|
|
|
|
|
powerupColorData[PowerupType::SPEED] = DARK_BLUE; |
|
|
|
|
|
|
|
powerupColorData[PowerupType::SHOTS] = DARK_RED; |
|
|
|
|
|
|
|
powerupColorData[PowerupType::STOP] = RED; |
|
|
|
|
|
|
|
powerupColorData[PowerupType::SHIELD] = CYAN; |
|
|
|
|
|
|
|
powerupColorData[PowerupType::CAMO] = MAGENTA; |
|
|
|
|
|
|
|
powerupColorData[PowerupType::MAP] = GREEN; |
|
|
|
|
|
|
|
powerupColorData[PowerupType::COIN] = BLUE; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Powerup::Powerup(Mesh mesh, vec3d pos, float rot, PowerupType type)
|
|
|
|
|
|
|
|
: type(type), col(game->powerupColorData[type]), Object{ mesh,pos,rot,0.375f } {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Powerup::Update(float fElapsedTime) { |
|
|
|
|
|
|
|
aliveTime += fElapsedTime; |
|
|
|
|
|
|
|
colorCycle = std::sinf(10 * aliveTime); |
|
|
|
|
|
|
|
col = game->powerupColorData[type] * colorCycle; |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FaceBall::SpawnPowerup(PowerupType type, vec3d pos) { |
|
|
|
|
|
|
|
Mesh& mesh = (type <= PowerupType::SHOTS) ? powerup : powerup2; |
|
|
|
|
|
|
|
powerups.push_back({ mesh,pos,0,type }); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void FaceBall::ConvertBulletColor(Mesh& bullet, Pixel col) { |
|
|
|
void FaceBall::ConvertBulletColor(Mesh& bullet, Pixel col) { |
|
|
|
for (Triangle& t : bullet.tris) { |
|
|
|
for (Triangle& t : bullet.tris) { |
|
|
|
t.col[0] = col; |
|
|
|
t.col[0] = col; |
|
|
@ -234,6 +279,9 @@ void FaceBall::LoadLevel(int level) |
|
|
|
bool FaceBall::CheckCollision(vec3d movementVector,vf2d pos,float radius){ |
|
|
|
bool FaceBall::CheckCollision(vec3d movementVector,vf2d pos,float radius){ |
|
|
|
utils::geom2d::circle<float>newPos{ {pos.x + movementVector.x,pos.y + movementVector.z},radius }; |
|
|
|
utils::geom2d::circle<float>newPos{ {pos.x + movementVector.x,pos.y + movementVector.z},radius }; |
|
|
|
bool collisionOccured = false; |
|
|
|
bool collisionOccured = false; |
|
|
|
|
|
|
|
if (pos.x - radius > game->MAP_SIZE.x || pos.x + radius<0 || pos.y - radius>game->MAP_SIZE.y || pos.y + radius < 0) { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
for (int y = -1; y <= 1; y++) { |
|
|
|
for (int y = -1; y <= 1; y++) { |
|
|
|
for (int x = -1; x <= 1; x++) { |
|
|
|
for (int x = -1; x <= 1; x++) { |
|
|
|
int offsetX = (int)pos.x + x; |
|
|
|
int offsetX = (int)pos.x + x; |
|
|
@ -494,6 +542,8 @@ int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& |
|
|
|
vec3d* outside_points[3]; int nOutsidePointCount = 0; |
|
|
|
vec3d* outside_points[3]; int nOutsidePointCount = 0; |
|
|
|
vec2d* inside_tex[3]; int nInsideTexCount = 0; |
|
|
|
vec2d* inside_tex[3]; int nInsideTexCount = 0; |
|
|
|
vec2d* outside_tex[3]; int nOutsideTexCount = 0; |
|
|
|
vec2d* outside_tex[3]; int nOutsideTexCount = 0; |
|
|
|
|
|
|
|
Pixel* inside_col[3]; int nInsideColCount = 0; |
|
|
|
|
|
|
|
Pixel* outside_col[3]; int nOutsideColCount = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get signed distance of each point in triangle to plane
|
|
|
|
// Get signed distance of each point in triangle to plane
|
|
|
@ -501,21 +551,21 @@ int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& |
|
|
|
float d1 = dist(in_tri.p[1]); |
|
|
|
float d1 = dist(in_tri.p[1]); |
|
|
|
float d2 = dist(in_tri.p[2]); |
|
|
|
float d2 = dist(in_tri.p[2]); |
|
|
|
|
|
|
|
|
|
|
|
if (d0 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[0]; inside_tex[nInsideTexCount++] = &in_tri.uv[0]; } |
|
|
|
if (d0 >= 0) { inside_points[nInsidePointCount++] = &in_tri.p[0]; inside_tex[nInsideTexCount++] = &in_tri.uv[0]; inside_col[nInsideColCount++] = &in_tri.col[0]; } |
|
|
|
else { |
|
|
|
else { |
|
|
|
outside_points[nOutsidePointCount++] = &in_tri.p[0]; outside_tex[nOutsideTexCount++] = &in_tri.uv[0]; |
|
|
|
outside_points[nOutsidePointCount++] = &in_tri.p[0]; outside_tex[nOutsideTexCount++] = &in_tri.uv[0]; outside_col[nOutsideColCount++] = &in_tri.col[0]; |
|
|
|
} |
|
|
|
} |
|
|
|
if (d1 >= 0) { |
|
|
|
if (d1 >= 0) { |
|
|
|
inside_points[nInsidePointCount++] = &in_tri.p[1]; inside_tex[nInsideTexCount++] = &in_tri.uv[1]; |
|
|
|
inside_points[nInsidePointCount++] = &in_tri.p[1]; inside_tex[nInsideTexCount++] = &in_tri.uv[1]; inside_col[nInsideColCount++] = &in_tri.col[1]; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
outside_points[nOutsidePointCount++] = &in_tri.p[1]; outside_tex[nOutsideTexCount++] = &in_tri.uv[1]; |
|
|
|
outside_points[nOutsidePointCount++] = &in_tri.p[1]; outside_tex[nOutsideTexCount++] = &in_tri.uv[1]; outside_col[nOutsideColCount++] = &in_tri.col[1]; |
|
|
|
} |
|
|
|
} |
|
|
|
if (d2 >= 0) { |
|
|
|
if (d2 >= 0) { |
|
|
|
inside_points[nInsidePointCount++] = &in_tri.p[2]; inside_tex[nInsideTexCount++] = &in_tri.uv[2]; |
|
|
|
inside_points[nInsidePointCount++] = &in_tri.p[2]; inside_tex[nInsideTexCount++] = &in_tri.uv[2]; inside_col[nInsideColCount++] = &in_tri.col[2]; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
outside_points[nOutsidePointCount++] = &in_tri.p[2]; outside_tex[nOutsideTexCount++] = &in_tri.uv[2]; |
|
|
|
outside_points[nOutsidePointCount++] = &in_tri.p[2]; outside_tex[nOutsideTexCount++] = &in_tri.uv[2]; outside_col[nOutsideColCount++] = &in_tri.col[2]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Now classify triangle points, and break the input triangle into
|
|
|
|
// Now classify triangle points, and break the input triangle into
|
|
|
@ -553,6 +603,7 @@ int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& |
|
|
|
// The inside point is valid, so keep that...
|
|
|
|
// The inside point is valid, so keep that...
|
|
|
|
out_tri1.p[0] = *inside_points[0]; |
|
|
|
out_tri1.p[0] = *inside_points[0]; |
|
|
|
out_tri1.uv[0] = *inside_tex[0]; |
|
|
|
out_tri1.uv[0] = *inside_tex[0]; |
|
|
|
|
|
|
|
out_tri1.col[0] = *inside_col[0]; |
|
|
|
|
|
|
|
|
|
|
|
// but the two new points are at the locations where the
|
|
|
|
// but the two new points are at the locations where the
|
|
|
|
// original sides of the triangle (lines) intersect with the plane
|
|
|
|
// original sides of the triangle (lines) intersect with the plane
|
|
|
@ -560,11 +611,19 @@ int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& |
|
|
|
out_tri1.p[1] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t); |
|
|
|
out_tri1.p[1] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t); |
|
|
|
out_tri1.uv[1].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u; |
|
|
|
out_tri1.uv[1].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u; |
|
|
|
out_tri1.uv[1].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v; |
|
|
|
out_tri1.uv[1].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v; |
|
|
|
|
|
|
|
out_tri1.col[1].r = t * (outside_col[0]->r - inside_col[0]->r) + inside_col[0]->r; |
|
|
|
|
|
|
|
out_tri1.col[1].g = t * (outside_col[0]->g - inside_col[0]->g) + inside_col[0]->g; |
|
|
|
|
|
|
|
out_tri1.col[1].b = t * (outside_col[0]->b - inside_col[0]->b) + inside_col[0]->b; |
|
|
|
|
|
|
|
//out_tri1.col[1].a = t * (outside_col[0]->a - inside_col[0]->a) + inside_col[0]->a;
|
|
|
|
out_tri1.uv[1].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w; |
|
|
|
out_tri1.uv[1].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w; |
|
|
|
|
|
|
|
|
|
|
|
out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[1], t); |
|
|
|
out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[1], t); |
|
|
|
out_tri1.uv[2].u = t * (outside_tex[1]->u - inside_tex[0]->u) + inside_tex[0]->u; |
|
|
|
out_tri1.uv[2].u = t * (outside_tex[1]->u - inside_tex[0]->u) + inside_tex[0]->u; |
|
|
|
out_tri1.uv[2].v = t * (outside_tex[1]->v - inside_tex[0]->v) + inside_tex[0]->v; |
|
|
|
out_tri1.uv[2].v = t * (outside_tex[1]->v - inside_tex[0]->v) + inside_tex[0]->v; |
|
|
|
|
|
|
|
out_tri1.col[2].r = t * (outside_col[1]->r - inside_col[0]->r) + inside_col[0]->r; |
|
|
|
|
|
|
|
out_tri1.col[2].g = t * (outside_col[1]->g - inside_col[0]->g) + inside_col[0]->g; |
|
|
|
|
|
|
|
out_tri1.col[2].b = t * (outside_col[1]->b - inside_col[0]->b) + inside_col[0]->b; |
|
|
|
|
|
|
|
//out_tri1.col[2].a = t * (outside_col[1]->a - inside_col[0]->a) + inside_col[0]->a;
|
|
|
|
out_tri1.uv[2].w = t * (outside_tex[1]->w - inside_tex[0]->w) + inside_tex[0]->w; |
|
|
|
out_tri1.uv[2].w = t * (outside_tex[1]->w - inside_tex[0]->w) + inside_tex[0]->w; |
|
|
|
|
|
|
|
|
|
|
|
return 1; // Return the newly formed single triangle
|
|
|
|
return 1; // Return the newly formed single triangle
|
|
|
@ -593,11 +652,17 @@ int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& |
|
|
|
out_tri1.p[1] = *inside_points[1]; |
|
|
|
out_tri1.p[1] = *inside_points[1]; |
|
|
|
out_tri1.uv[0] = *inside_tex[0]; |
|
|
|
out_tri1.uv[0] = *inside_tex[0]; |
|
|
|
out_tri1.uv[1] = *inside_tex[1]; |
|
|
|
out_tri1.uv[1] = *inside_tex[1]; |
|
|
|
|
|
|
|
out_tri1.col[0] = *inside_col[0]; |
|
|
|
|
|
|
|
out_tri1.col[1] = *inside_col[1]; |
|
|
|
|
|
|
|
|
|
|
|
float t; |
|
|
|
float t; |
|
|
|
out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t); |
|
|
|
out_tri1.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[0], *outside_points[0], t); |
|
|
|
out_tri1.uv[2].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u; |
|
|
|
out_tri1.uv[2].u = t * (outside_tex[0]->u - inside_tex[0]->u) + inside_tex[0]->u; |
|
|
|
out_tri1.uv[2].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v; |
|
|
|
out_tri1.uv[2].v = t * (outside_tex[0]->v - inside_tex[0]->v) + inside_tex[0]->v; |
|
|
|
|
|
|
|
out_tri1.col[2].r = t * (outside_col[0]->r - inside_col[0]->r) + inside_col[0]->r; |
|
|
|
|
|
|
|
out_tri1.col[2].g = t * (outside_col[0]->g - inside_col[0]->g) + inside_col[0]->g; |
|
|
|
|
|
|
|
out_tri1.col[2].b = t * (outside_col[0]->b - inside_col[0]->b) + inside_col[0]->b; |
|
|
|
|
|
|
|
//out_tri1.col[2].a = t * (outside_col[0]->a - inside_col[0]->a) + inside_col[0]->a;
|
|
|
|
out_tri1.uv[2].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w; |
|
|
|
out_tri1.uv[2].w = t * (outside_tex[0]->w - inside_tex[0]->w) + inside_tex[0]->w; |
|
|
|
|
|
|
|
|
|
|
|
// The second triangle is composed of one of he inside points, a
|
|
|
|
// The second triangle is composed of one of he inside points, a
|
|
|
@ -605,11 +670,17 @@ int FaceBall::Triangle_ClipAgainstPlane(vec3d plane_p, vec3d plane_n, Triangle& |
|
|
|
// triangle and the plane, and the newly created point above
|
|
|
|
// triangle and the plane, and the newly created point above
|
|
|
|
out_tri2.p[0] = *inside_points[1]; |
|
|
|
out_tri2.p[0] = *inside_points[1]; |
|
|
|
out_tri2.uv[0] = *inside_tex[1]; |
|
|
|
out_tri2.uv[0] = *inside_tex[1]; |
|
|
|
|
|
|
|
out_tri2.col[0] = *inside_col[1]; |
|
|
|
out_tri2.p[1] = out_tri1.p[2]; |
|
|
|
out_tri2.p[1] = out_tri1.p[2]; |
|
|
|
out_tri2.uv[1] = out_tri1.uv[2]; |
|
|
|
out_tri2.uv[1] = out_tri1.uv[2]; |
|
|
|
|
|
|
|
out_tri2.col[1] = out_tri1.col[2]; |
|
|
|
out_tri2.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[1], *outside_points[0], t); |
|
|
|
out_tri2.p[2] = Vector_IntersectPlane(plane_p, plane_n, *inside_points[1], *outside_points[0], t); |
|
|
|
out_tri2.uv[2].u = t * (outside_tex[0]->u - inside_tex[1]->u) + inside_tex[1]->u; |
|
|
|
out_tri2.uv[2].u = t * (outside_tex[0]->u - inside_tex[1]->u) + inside_tex[1]->u; |
|
|
|
out_tri2.uv[2].v = t * (outside_tex[0]->v - inside_tex[1]->v) + inside_tex[1]->v; |
|
|
|
out_tri2.uv[2].v = t * (outside_tex[0]->v - inside_tex[1]->v) + inside_tex[1]->v; |
|
|
|
|
|
|
|
out_tri1.col[2].r = t * (outside_col[0]->r - inside_col[1]->r) + inside_col[1]->r; |
|
|
|
|
|
|
|
out_tri1.col[2].g = t * (outside_col[0]->g - inside_col[1]->g) + inside_col[1]->g; |
|
|
|
|
|
|
|
out_tri1.col[2].b = t * (outside_col[0]->b - inside_col[1]->b) + inside_col[1]->b; |
|
|
|
|
|
|
|
//out_tri1.col[2].a = t * (outside_col[0]->a - inside_col[1]->a) + inside_col[1]->a;
|
|
|
|
out_tri2.uv[2].w = t * (outside_tex[0]->w - inside_tex[1]->w) + inside_tex[1]->w; |
|
|
|
out_tri2.uv[2].w = t * (outside_tex[0]->w - inside_tex[1]->w) + inside_tex[1]->w; |
|
|
|
return 2; // Return two newly formed triangles which form a quad
|
|
|
|
return 2; // Return two newly formed triangles which form a quad
|
|
|
|
} |
|
|
|
} |
|
|
@ -753,6 +824,140 @@ void FaceBall::RenderMesh(mat4x4&matView,std::vector<Triangle>&vecTrianglesToRas |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FaceBall::RenderPowerupMesh(mat4x4& matView, std::vector<Triangle>& vecTrianglesToRaster, Powerup&p) { |
|
|
|
|
|
|
|
for (int i = 0; i < 2; i++) { |
|
|
|
|
|
|
|
for (auto& tri : p.mesh.tris) { |
|
|
|
|
|
|
|
Triangle triProjected, triTransformed, triViewed; |
|
|
|
|
|
|
|
mat4x4 localMat = Matrix_MakeIdentity(); |
|
|
|
|
|
|
|
mat4x4 rotMat = Matrix_MakeRotationY(p.rot); |
|
|
|
|
|
|
|
if (i) { |
|
|
|
|
|
|
|
mat4x4 flipMat = Matrix_MakeRotationX(PI); |
|
|
|
|
|
|
|
rotMat = Matrix_MultiplyMatrix(rotMat, flipMat); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
localMat = Matrix_MultiplyMatrix(localMat, rotMat); |
|
|
|
|
|
|
|
mat4x4 matTrans = Matrix_MakeTranslation(p.pos.x, p.pos.y+(i?0.375f:0), p.pos.z); |
|
|
|
|
|
|
|
localMat = Matrix_MultiplyMatrix(localMat, matTrans); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
triTransformed.p[0] = Matrix_MultiplyVector(localMat, tri.p[0]); |
|
|
|
|
|
|
|
triTransformed.p[1] = Matrix_MultiplyVector(localMat, tri.p[1]); |
|
|
|
|
|
|
|
triTransformed.p[2] = Matrix_MultiplyVector(localMat, tri.p[2]); |
|
|
|
|
|
|
|
triTransformed.uv[0] = tri.uv[0]; |
|
|
|
|
|
|
|
triTransformed.uv[1] = tri.uv[1]; |
|
|
|
|
|
|
|
triTransformed.uv[2] = tri.uv[2]; |
|
|
|
|
|
|
|
triTransformed.col[0] = tri.col[0]; |
|
|
|
|
|
|
|
triTransformed.col[1] = tri.col[1]; |
|
|
|
|
|
|
|
triTransformed.col[2] = tri.col[2]; |
|
|
|
|
|
|
|
triTransformed.tex = tri.tex; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3d normal, line1, line2; |
|
|
|
|
|
|
|
line1 = Vector_Sub(triTransformed.p[1], triTransformed.p[0]); |
|
|
|
|
|
|
|
line2 = Vector_Sub(triTransformed.p[2], triTransformed.p[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
normal = Vector_CrossProduct(line1, line2); |
|
|
|
|
|
|
|
normal = Vector_Normalise(normal); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3d vCameraRay = Vector_Sub(triTransformed.p[0], freeRoam ? freeRoamCamera : player.GetPos()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Vector_DotProduct(normal, vCameraRay) < 0) { |
|
|
|
|
|
|
|
vec3d light_dir = Vector_Mul(vLookDir, -1); |
|
|
|
|
|
|
|
light_dir = Vector_Normalise(light_dir); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float dp = std::max(0.7f, Vector_DotProduct(light_dir, normal)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
triViewed.p[0] = Matrix_MultiplyVector(matView, triTransformed.p[0]); |
|
|
|
|
|
|
|
triViewed.p[1] = Matrix_MultiplyVector(matView, triTransformed.p[1]); |
|
|
|
|
|
|
|
triViewed.p[2] = Matrix_MultiplyVector(matView, triTransformed.p[2]); |
|
|
|
|
|
|
|
triViewed.uv[0] = triTransformed.uv[0]; |
|
|
|
|
|
|
|
triViewed.uv[1] = triTransformed.uv[1]; |
|
|
|
|
|
|
|
triViewed.uv[2] = triTransformed.uv[2]; |
|
|
|
|
|
|
|
triViewed.col[0] = Pixel(triTransformed.col[0].r * dp * dp, triTransformed.col[0].g * dp * dp, triTransformed.col[0].b * dp * dp); |
|
|
|
|
|
|
|
triViewed.col[1] = Pixel(triTransformed.col[1].r * dp * dp, triTransformed.col[1].g * dp * dp, triTransformed.col[1].b * dp * dp); |
|
|
|
|
|
|
|
triViewed.col[2] = Pixel(triTransformed.col[2].r * dp * dp, triTransformed.col[2].g * dp * dp, triTransformed.col[2].b * dp * dp); |
|
|
|
|
|
|
|
Pixel originalCol[3] = { triViewed.col[0],triViewed.col[1],triViewed.col[2] }; |
|
|
|
|
|
|
|
float dist = std::sqrtf(std::powf((freeRoam ? freeRoamCamera : player.GetPos()).x - triTransformed.p[0].x, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).y - triTransformed.p[0].y, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).z - triTransformed.p[0].z, 2)); |
|
|
|
|
|
|
|
float dist2 = std::sqrtf(std::powf((freeRoam ? freeRoamCamera : player.GetPos()).x - triTransformed.p[1].x, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).y - triTransformed.p[1].y, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).z - triTransformed.p[1].z, 2)); |
|
|
|
|
|
|
|
float dist3 = std::sqrtf(std::powf((freeRoam ? freeRoamCamera : player.GetPos()).x - triTransformed.p[2].x, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).y - triTransformed.p[2].y, 2) + std::powf((freeRoam ? freeRoamCamera : player.GetPos()).z - triTransformed.p[2].z, 2)); |
|
|
|
|
|
|
|
float colorMult = dist > 5 * PI / 3 ? 0 : std::sinf(0.3 * dist + PI / 2); |
|
|
|
|
|
|
|
float colorMult2 = dist2 > 5 * PI / 3 ? 0 : std::sinf(0.3 * dist2 + PI / 2); |
|
|
|
|
|
|
|
float colorMult3 = dist3 > 5 * PI / 3 ? 0 : std::sinf(0.3 * dist3 + PI / 2); |
|
|
|
|
|
|
|
triViewed.col[0] = Pixel(triViewed.col[0].r * colorMult, triViewed.col[0].g * colorMult, triViewed.col[0].b * colorMult); |
|
|
|
|
|
|
|
triViewed.col[1] = Pixel(triViewed.col[1].r * colorMult2, triViewed.col[1].g * colorMult2, triViewed.col[1].b * colorMult2); |
|
|
|
|
|
|
|
triViewed.col[2] = Pixel(triViewed.col[2].r * colorMult3, triViewed.col[2].g * colorMult3, triViewed.col[2].b * colorMult3); |
|
|
|
|
|
|
|
triViewed.tex = triTransformed.tex; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (Bullet& b : bullets) { |
|
|
|
|
|
|
|
float dist = std::sqrtf(std::powf(b.pos.x - triTransformed.p[0].x, 2) + std::powf(b.pos.y - triTransformed.p[0].y, 2) + std::powf(b.pos.z - triTransformed.p[0].z, 2)); |
|
|
|
|
|
|
|
float dist2 = std::sqrtf(std::powf(b.pos.x - triTransformed.p[1].x, 2) + std::powf(b.pos.y - triTransformed.p[1].y, 2) + std::powf(b.pos.z - triTransformed.p[1].z, 2)); |
|
|
|
|
|
|
|
float dist3 = std::sqrtf(std::powf(b.pos.x - triTransformed.p[2].x, 2) + std::powf(b.pos.y - triTransformed.p[2].y, 2) + std::powf(b.pos.z - triTransformed.p[2].z, 2)); |
|
|
|
|
|
|
|
float colorMult = (dist < 2 ? std::sinf(0.75 * dist + PI / 2) * 4 : 1); |
|
|
|
|
|
|
|
float colorMult2 = (dist2 < 2 ? std::sinf(0.75 * dist2 + PI / 2) * 4 : 1); |
|
|
|
|
|
|
|
float colorMult3 = (dist3 < 2 ? std::sinf(0.75 * dist3 + PI / 2) * 4 : 1); |
|
|
|
|
|
|
|
Pixel lightCol = b.col / 2 + Pixel{ 128, 128, 128 }; |
|
|
|
|
|
|
|
if (dist < 2) { triViewed.col[0] = Pixel(std::min(255, std::max((int)originalCol[0].r, (int)(originalCol[0].r * colorMult / float(255.f / lightCol.r)))), std::min(255, std::max((int)originalCol[0].g, (int)(originalCol[0].g * colorMult / float(255.f / lightCol.g)))), std::min(255, std::max((int)originalCol[0].b, (int)(originalCol[0].b * colorMult / float(255.f / lightCol.b))))); } |
|
|
|
|
|
|
|
if (dist2 < 2) { triViewed.col[1] = Pixel(std::min(255, std::max((int)originalCol[1].r, (int)(originalCol[1].r * colorMult2 / float(255.f / lightCol.r)))), std::min(255, std::max((int)originalCol[1].g, (int)(originalCol[1].g * colorMult2 / float(255.f / lightCol.g)))), std::min(255, std::max((int)originalCol[1].b, (int)(originalCol[1].b * colorMult2 / float(255.f / lightCol.b))))); } |
|
|
|
|
|
|
|
if (dist3 < 2) { triViewed.col[2] = Pixel(std::min(255, std::max((int)originalCol[2].r, (int)(originalCol[2].r * colorMult3 / float(255.f / lightCol.r)))), std::min(255, std::max((int)originalCol[2].g, (int)(originalCol[2].g * colorMult3 / float(255.f / lightCol.g)))), std::min(255, std::max((int)originalCol[2].b, (int)(originalCol[2].b * colorMult3 / float(255.f / lightCol.b))))); } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//triViewed.col = triTransformed.col;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int nClippedTriangles = 0; |
|
|
|
|
|
|
|
Triangle clipped[2]; |
|
|
|
|
|
|
|
nClippedTriangles = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.1f }, { 0.0f, 0.0f, 1.0f }, triViewed, clipped[0], clipped[1]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int n = 0; n < nClippedTriangles; n++) { |
|
|
|
|
|
|
|
// Project triangles from 3D --> 2D
|
|
|
|
|
|
|
|
triProjected.p[0] = Matrix_MultiplyVector(matProj, clipped[n].p[0]); |
|
|
|
|
|
|
|
triProjected.p[1] = Matrix_MultiplyVector(matProj, clipped[n].p[1]); |
|
|
|
|
|
|
|
triProjected.p[2] = Matrix_MultiplyVector(matProj, clipped[n].p[2]); |
|
|
|
|
|
|
|
triProjected.col[0] = clipped[n].col[0]; |
|
|
|
|
|
|
|
triProjected.col[1] = clipped[n].col[1]; |
|
|
|
|
|
|
|
triProjected.col[2] = clipped[n].col[2]; |
|
|
|
|
|
|
|
triProjected.tex = clipped[n].tex; |
|
|
|
|
|
|
|
triProjected.uv[0] = clipped[n].uv[0]; |
|
|
|
|
|
|
|
triProjected.uv[1] = clipped[n].uv[1]; |
|
|
|
|
|
|
|
triProjected.uv[2] = clipped[n].uv[2]; |
|
|
|
|
|
|
|
triProjected.uv[0].u = triProjected.uv[0].u / triProjected.p[0].w; |
|
|
|
|
|
|
|
triProjected.uv[1].u = triProjected.uv[1].u / triProjected.p[1].w; |
|
|
|
|
|
|
|
triProjected.uv[2].u = triProjected.uv[2].u / triProjected.p[2].w; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
triProjected.uv[0].v = triProjected.uv[0].v / triProjected.p[0].w; |
|
|
|
|
|
|
|
triProjected.uv[1].v = triProjected.uv[1].v / triProjected.p[1].w; |
|
|
|
|
|
|
|
triProjected.uv[2].v = triProjected.uv[2].v / triProjected.p[2].w; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
triProjected.uv[0].w = 1.0f / triProjected.p[0].w; |
|
|
|
|
|
|
|
triProjected.uv[1].w = 1.0f / triProjected.p[1].w; |
|
|
|
|
|
|
|
triProjected.uv[2].w = 1.0f / triProjected.p[2].w; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
triProjected.p[0] = Vector_Div(triProjected.p[0], triProjected.p[0].w); |
|
|
|
|
|
|
|
triProjected.p[1] = Vector_Div(triProjected.p[1], triProjected.p[1].w); |
|
|
|
|
|
|
|
triProjected.p[2] = Vector_Div(triProjected.p[2], triProjected.p[2].w); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
triProjected.p[0].x *= -1.0f; |
|
|
|
|
|
|
|
triProjected.p[1].x *= -1.0f; |
|
|
|
|
|
|
|
triProjected.p[2].x *= -1.0f; |
|
|
|
|
|
|
|
triProjected.p[0].y *= -1.0f; |
|
|
|
|
|
|
|
triProjected.p[1].y *= -1.0f; |
|
|
|
|
|
|
|
triProjected.p[2].y *= -1.0f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Scale into view
|
|
|
|
|
|
|
|
vec3d vOffsetView = { 1,1,0 }; |
|
|
|
|
|
|
|
triProjected.p[0] = Vector_Add(triProjected.p[0], vOffsetView); |
|
|
|
|
|
|
|
triProjected.p[1] = Vector_Add(triProjected.p[1], vOffsetView); |
|
|
|
|
|
|
|
triProjected.p[2] = Vector_Add(triProjected.p[2], vOffsetView); |
|
|
|
|
|
|
|
triProjected.p[0].x *= 0.5f * (float)ScreenWidth(); |
|
|
|
|
|
|
|
triProjected.p[0].y *= 0.5f * (float)ScreenHeight(); |
|
|
|
|
|
|
|
triProjected.p[1].x *= 0.5f * (float)ScreenWidth(); |
|
|
|
|
|
|
|
triProjected.p[1].y *= 0.5f * (float)ScreenHeight(); |
|
|
|
|
|
|
|
triProjected.p[2].x *= 0.5f * (float)ScreenWidth(); |
|
|
|
|
|
|
|
triProjected.p[2].y *= 0.5f * (float)ScreenHeight(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vecTrianglesToRaster.push_back(triProjected); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void FaceBall::RenderMeshDeathScreen(mat4x4& matView, std::vector<Triangle>& vecTrianglesToRaster, Object& o) { |
|
|
|
void FaceBall::RenderMeshDeathScreen(mat4x4& matView, std::vector<Triangle>& vecTrianglesToRaster, Object& o) { |
|
|
|
for (auto& tri : o.mesh.tris) { |
|
|
|
for (auto& tri : o.mesh.tris) { |
|
|
|
Triangle triProjected, triTransformed, triViewed; |
|
|
|
Triangle triProjected, triTransformed, triViewed; |
|
|
@ -914,7 +1119,12 @@ void FaceBall::RenderWorld() { |
|
|
|
t.col[0] = t.col[1] = t.col[2] = {0,(uint8_t)(std::abs(std::sinf(2*PI*gameTimer)) * 255),0}; |
|
|
|
t.col[0] = t.col[1] = t.col[2] = {0,(uint8_t)(std::abs(std::sinf(2*PI*gameTimer)) * 255),0}; |
|
|
|
} |
|
|
|
} |
|
|
|
for (auto& enemy : enemies) { |
|
|
|
for (auto& enemy : enemies) { |
|
|
|
RenderMesh(matView, vecTrianglesToRaster, enemy); |
|
|
|
if (enemy.blinkingAmt > 0.4f) { |
|
|
|
|
|
|
|
RenderMesh(matView, vecTrianglesToRaster, enemy); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
for (auto& powerup : powerups) { |
|
|
|
|
|
|
|
RenderPowerupMesh(matView, vecTrianglesToRaster, powerup); |
|
|
|
} |
|
|
|
} |
|
|
|
for (auto& bullet : bullets) { |
|
|
|
for (auto& bullet : bullets) { |
|
|
|
RenderBulletMesh(matView, vecTrianglesToRasterTranslucent, bullet); |
|
|
|
RenderBulletMesh(matView, vecTrianglesToRasterTranslucent, bullet); |
|
|
@ -1286,11 +1496,15 @@ bool FaceBall::OnUserCreate() |
|
|
|
life1 = new Decal(new Sprite("assets/life1.png")); |
|
|
|
life1 = new Decal(new Sprite("assets/life1.png")); |
|
|
|
crosshair = new Decal(new Sprite("assets/crosshair.png")); |
|
|
|
crosshair = new Decal(new Sprite("assets/crosshair.png")); |
|
|
|
hudmeter = new Decal(new Sprite("assets/hudmeter.png")); |
|
|
|
hudmeter = new Decal(new Sprite("assets/hudmeter.png")); |
|
|
|
|
|
|
|
powerup_tex = new Decal(new Sprite("assets/powerup.png")); |
|
|
|
|
|
|
|
powerup2_tex = new Decal(new Sprite("assets/powerup2.png")); |
|
|
|
|
|
|
|
|
|
|
|
enemy_ShootMe = { "assets/enemies/ShootMe.obj", enemy_ShootMe_tex }; |
|
|
|
enemy_ShootMe = { "assets/enemies/ShootMe.obj", enemy_ShootMe_tex }; |
|
|
|
enemy_IShoot = { "assets/enemies/IShoot.obj", enemy_IShoot_tex }; |
|
|
|
enemy_IShoot = { "assets/enemies/IShoot.obj", enemy_IShoot_tex }; |
|
|
|
enemy_Sonar = { "assets/enemies/Sonar.obj", enemy_Sonar_tex }; |
|
|
|
enemy_Sonar = { "assets/enemies/Sonar.obj", enemy_Sonar_tex }; |
|
|
|
bullet = { "assets/enemies/bullet.obj",bullet_tex }; |
|
|
|
bullet = { "assets/enemies/bullet.obj",bullet_tex }; |
|
|
|
|
|
|
|
powerup = { "assets/Powerup.obj",powerup_tex}; |
|
|
|
|
|
|
|
powerup2 = { "assets/Powerup2.obj",powerup2_tex }; |
|
|
|
mapExit = { "assets/Exit.obj",dot }; |
|
|
|
mapExit = { "assets/Exit.obj",dot }; |
|
|
|
mapWalls.texture = wall_tex; |
|
|
|
mapWalls.texture = wall_tex; |
|
|
|
mapFloor.texture = floor_tex; |
|
|
|
mapFloor.texture = floor_tex; |
|
|
@ -1356,7 +1570,7 @@ bool Bullet::Update(float fElapsedTime) { |
|
|
|
Enemy& enemy = game->enemies[collided_enemy]; |
|
|
|
Enemy& enemy = game->enemies[collided_enemy]; |
|
|
|
enemy.Hurt(); |
|
|
|
enemy.Hurt(); |
|
|
|
if (enemy.isDead()) { |
|
|
|
if (enemy.isDead()) { |
|
|
|
game->SubtractTag(); |
|
|
|
enemy.OnDeathEvent(); |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
@ -1396,6 +1610,99 @@ void FaceBall::HurtPlayer(EnemyID id,int damage,bool blinking) { |
|
|
|
screenCol = enemyData[lastHitBy].col; |
|
|
|
screenCol = enemyData[lastHitBy].col; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FaceBall::Display3DKillerModel() { |
|
|
|
|
|
|
|
// Set up rotation matrices
|
|
|
|
|
|
|
|
mat4x4 matRotZ, matRotX, matWorld; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
matRotZ = Matrix_MakeRotationZ(0); |
|
|
|
|
|
|
|
matRotX = Matrix_MakeRotationX(0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//matTrans = Matrix_MakeTranslation(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
matWorld = Matrix_MakeIdentity(); |
|
|
|
|
|
|
|
matWorld = Matrix_MultiplyMatrix(matRotZ, matRotX); |
|
|
|
|
|
|
|
//matWorld = Matrix_MultiplyMatrix(matWorld, matTrans);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3d vUp = { 0,1,0 }; |
|
|
|
|
|
|
|
vec3d vTarget = { 0,sinf(0.0944495052),cosf(0.0944495052) }; |
|
|
|
|
|
|
|
mat4x4 matCameraRot = Matrix_MakeRotationY(3.12987614 - PI / 2); |
|
|
|
|
|
|
|
vLookDir = Matrix_MultiplyVector(matCameraRot, vTarget); |
|
|
|
|
|
|
|
vec3d camera = { 0.758110702,0.222716771,3.00489759 }; |
|
|
|
|
|
|
|
vTarget = Vector_Add(camera, vLookDir); |
|
|
|
|
|
|
|
mat4x4 matCamera = Matrix_PointAt(camera, vTarget, vUp); |
|
|
|
|
|
|
|
mat4x4 matView = Matrix_QuickInverse(matCamera); |
|
|
|
|
|
|
|
std::vector<Triangle>vecTrianglesToRaster; |
|
|
|
|
|
|
|
Object o = { enemyData[lastHitBy].mesh,{0,0,3} }; |
|
|
|
|
|
|
|
RenderMeshDeathScreen(matView, vecTrianglesToRaster, o); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//std::sort(vecTrianglesToRaster.begin(),vecTrianglesToRaster.end(),[](triangle&t1,triangle&t2){return (t1.p[0].z+t1.p[1].z+t1.p[2].z)/3.0f>(t2.p[0].z+t2.p[1].z+t2.p[2].z)/3.0f;});
|
|
|
|
|
|
|
|
triRenderCount = 0; |
|
|
|
|
|
|
|
for (auto& triToRaster : vecTrianglesToRaster) { |
|
|
|
|
|
|
|
Triangle clipped[2]; |
|
|
|
|
|
|
|
std::list<Triangle>listTriangles; |
|
|
|
|
|
|
|
listTriangles.push_back(triToRaster); |
|
|
|
|
|
|
|
int nNewTriangles = 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int p = 0; p < 4; p++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int nTrisToAdd = 0; |
|
|
|
|
|
|
|
while (nNewTriangles > 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Take triangle from front of queue
|
|
|
|
|
|
|
|
Triangle test = listTriangles.front(); |
|
|
|
|
|
|
|
listTriangles.pop_front(); |
|
|
|
|
|
|
|
nNewTriangles--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Clip it against a plane. We only need to test each
|
|
|
|
|
|
|
|
// subsequent plane, against subsequent new triangles
|
|
|
|
|
|
|
|
// as all triangles after a plane clip are guaranteed
|
|
|
|
|
|
|
|
// to lie on the inside of the plane. I like how this
|
|
|
|
|
|
|
|
// comment is almost completely and utterly justified
|
|
|
|
|
|
|
|
switch (p) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case 0: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
|
|
|
case 1: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, (float)ScreenHeight() - 1, 0.0f }, { 0.0f, -1.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
|
|
|
case 2: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
|
|
|
case 3: nTrisToAdd = Triangle_ClipAgainstPlane({ (float)ScreenWidth() - 1, 0.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Clipping may yield a variable number of triangles, so
|
|
|
|
|
|
|
|
// add these new ones to the back of the queue for subsequent
|
|
|
|
|
|
|
|
// clipping against next planes
|
|
|
|
|
|
|
|
for (int w = 0; w < nTrisToAdd; w++) |
|
|
|
|
|
|
|
listTriangles.push_back(clipped[w]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
nNewTriangles = listTriangles.size(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& t : listTriangles) { |
|
|
|
|
|
|
|
// Rasterize triangle
|
|
|
|
|
|
|
|
SetDecalStructure(DecalStructure::LIST); |
|
|
|
|
|
|
|
SetDecalMode(DecalMode::NORMAL); |
|
|
|
|
|
|
|
DrawPolygonDecal(t.tex, { |
|
|
|
|
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
|
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
|
|
|
|
{t.p[2].x, t.p[2].y} |
|
|
|
|
|
|
|
}, { |
|
|
|
|
|
|
|
{t.uv[0].u,t.uv[0].v}, |
|
|
|
|
|
|
|
{t.uv[1].u,t.uv[1].v}, |
|
|
|
|
|
|
|
{t.uv[2].u,t.uv[2].v}, |
|
|
|
|
|
|
|
}, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { t.col[0],t.col[1],t.col[2] }); |
|
|
|
|
|
|
|
/*SetDecalMode(DecalMode::WIREFRAME);
|
|
|
|
|
|
|
|
DrawPolygonDecal(nullptr,{ |
|
|
|
|
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
|
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
|
|
|
|
{t.p[2].x, t.p[2].y} |
|
|
|
|
|
|
|
},{ |
|
|
|
|
|
|
|
{0,0}, |
|
|
|
|
|
|
|
{0,0}, |
|
|
|
|
|
|
|
{0,0}, |
|
|
|
|
|
|
|
}, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { BLACK,BLACK,BLACK });*/ |
|
|
|
|
|
|
|
SetDecalStructure(DecalStructure::FAN); |
|
|
|
|
|
|
|
triRenderCount++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void FaceBall::RenderHud(float fElapsedTime) { |
|
|
|
void FaceBall::RenderHud(float fElapsedTime) { |
|
|
|
if (hudShakeTime > 0) { |
|
|
|
if (hudShakeTime > 0) { |
|
|
|
hudShakeTime -= fElapsedTime; |
|
|
|
hudShakeTime -= fElapsedTime; |
|
|
@ -1412,96 +1719,7 @@ void FaceBall::RenderHud(float fElapsedTime) { |
|
|
|
FillRectDecal({ 0,0 }, { float(ScreenWidth()),float(ScreenHeight()) }); |
|
|
|
FillRectDecal({ 0,0 }, { float(ScreenWidth()),float(ScreenHeight()) }); |
|
|
|
std::string topText = enemyData[lastHitBy].name + " SAYS"; |
|
|
|
std::string topText = enemyData[lastHitBy].name + " SAYS"; |
|
|
|
std::string bottomText = "HAVE A NICE DAY !"; |
|
|
|
std::string bottomText = "HAVE A NICE DAY !"; |
|
|
|
// Set up rotation matrices
|
|
|
|
Display3DKillerModel(); |
|
|
|
mat4x4 matRotZ, matRotX, matWorld; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
matRotZ = Matrix_MakeRotationZ(0); |
|
|
|
|
|
|
|
matRotX = Matrix_MakeRotationX(0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//matTrans = Matrix_MakeTranslation(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
matWorld = Matrix_MakeIdentity(); |
|
|
|
|
|
|
|
matWorld = Matrix_MultiplyMatrix(matRotZ, matRotX); |
|
|
|
|
|
|
|
//matWorld = Matrix_MultiplyMatrix(matWorld, matTrans);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec3d vUp = { 0,1,0 }; |
|
|
|
|
|
|
|
vec3d vTarget = { 0,sinf(0.0944495052),cosf(0.0944495052) }; |
|
|
|
|
|
|
|
mat4x4 matCameraRot = Matrix_MakeRotationY(3.12987614 - PI / 2); |
|
|
|
|
|
|
|
vLookDir = Matrix_MultiplyVector(matCameraRot, vTarget); |
|
|
|
|
|
|
|
vec3d camera = { 0.758110702,0.222716771,3.00489759 }; |
|
|
|
|
|
|
|
vTarget = Vector_Add(camera, vLookDir); |
|
|
|
|
|
|
|
mat4x4 matCamera = Matrix_PointAt(camera, vTarget, vUp); |
|
|
|
|
|
|
|
mat4x4 matView = Matrix_QuickInverse(matCamera); |
|
|
|
|
|
|
|
std::vector<Triangle>vecTrianglesToRaster; |
|
|
|
|
|
|
|
Object o = { enemyData[lastHitBy].mesh,{0,0,3} }; |
|
|
|
|
|
|
|
RenderMeshDeathScreen(matView, vecTrianglesToRaster, o); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//std::sort(vecTrianglesToRaster.begin(),vecTrianglesToRaster.end(),[](triangle&t1,triangle&t2){return (t1.p[0].z+t1.p[1].z+t1.p[2].z)/3.0f>(t2.p[0].z+t2.p[1].z+t2.p[2].z)/3.0f;});
|
|
|
|
|
|
|
|
triRenderCount = 0; |
|
|
|
|
|
|
|
for (auto& triToRaster : vecTrianglesToRaster) { |
|
|
|
|
|
|
|
Triangle clipped[2]; |
|
|
|
|
|
|
|
std::list<Triangle>listTriangles; |
|
|
|
|
|
|
|
listTriangles.push_back(triToRaster); |
|
|
|
|
|
|
|
int nNewTriangles = 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int p = 0; p < 4; p++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int nTrisToAdd = 0; |
|
|
|
|
|
|
|
while (nNewTriangles > 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Take triangle from front of queue
|
|
|
|
|
|
|
|
Triangle test = listTriangles.front(); |
|
|
|
|
|
|
|
listTriangles.pop_front(); |
|
|
|
|
|
|
|
nNewTriangles--; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Clip it against a plane. We only need to test each
|
|
|
|
|
|
|
|
// subsequent plane, against subsequent new triangles
|
|
|
|
|
|
|
|
// as all triangles after a plane clip are guaranteed
|
|
|
|
|
|
|
|
// to lie on the inside of the plane. I like how this
|
|
|
|
|
|
|
|
// comment is almost completely and utterly justified
|
|
|
|
|
|
|
|
switch (p) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case 0: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
|
|
|
case 1: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, (float)ScreenHeight() - 1, 0.0f }, { 0.0f, -1.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
|
|
|
case 2: nTrisToAdd = Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
|
|
|
case 3: nTrisToAdd = Triangle_ClipAgainstPlane({ (float)ScreenWidth() - 1, 0.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, test, clipped[0], clipped[1]); break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Clipping may yield a variable number of triangles, so
|
|
|
|
|
|
|
|
// add these new ones to the back of the queue for subsequent
|
|
|
|
|
|
|
|
// clipping against next planes
|
|
|
|
|
|
|
|
for (int w = 0; w < nTrisToAdd; w++) |
|
|
|
|
|
|
|
listTriangles.push_back(clipped[w]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
nNewTriangles = listTriangles.size(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& t : listTriangles) { |
|
|
|
|
|
|
|
// Rasterize triangle
|
|
|
|
|
|
|
|
SetDecalStructure(DecalStructure::LIST); |
|
|
|
|
|
|
|
SetDecalMode(DecalMode::NORMAL); |
|
|
|
|
|
|
|
DrawPolygonDecal(t.tex, { |
|
|
|
|
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
|
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
|
|
|
|
{t.p[2].x, t.p[2].y} |
|
|
|
|
|
|
|
}, { |
|
|
|
|
|
|
|
{t.uv[0].u,t.uv[0].v}, |
|
|
|
|
|
|
|
{t.uv[1].u,t.uv[1].v}, |
|
|
|
|
|
|
|
{t.uv[2].u,t.uv[2].v}, |
|
|
|
|
|
|
|
}, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { t.col[0],t.col[1],t.col[2] }); |
|
|
|
|
|
|
|
/*SetDecalMode(DecalMode::WIREFRAME);
|
|
|
|
|
|
|
|
DrawPolygonDecal(nullptr,{ |
|
|
|
|
|
|
|
{t.p[0].x, t.p[0].y}, |
|
|
|
|
|
|
|
{t.p[1].x, t.p[1].y}, |
|
|
|
|
|
|
|
{t.p[2].x, t.p[2].y} |
|
|
|
|
|
|
|
},{ |
|
|
|
|
|
|
|
{0,0}, |
|
|
|
|
|
|
|
{0,0}, |
|
|
|
|
|
|
|
{0,0}, |
|
|
|
|
|
|
|
}, { t.uv[0].w,t.uv[1].w,t.uv[2].w }, { t.p[0].z,t.p[1].z,t.p[2].z }, { BLACK,BLACK,BLACK });*/ |
|
|
|
|
|
|
|
SetDecalStructure(DecalStructure::FAN); |
|
|
|
|
|
|
|
triRenderCount++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
DrawStringDecal({ (float)(ScreenWidth() / 2 - GetTextSize(topText).x / 2 * 3),140.f }, topText, { 96,96,255 }, { 3,6 }); |
|
|
|
DrawStringDecal({ (float)(ScreenWidth() / 2 - GetTextSize(topText).x / 2 * 3),140.f }, topText, { 96,96,255 }, { 3,6 }); |
|
|
|
DrawStringDecal({ float(ScreenWidth() / 2 - GetTextSize(bottomText).x / 2 * 3),float(ScreenHeight() - 140.f) }, bottomText, { 96,96,255 }, { 3,6 }); |
|
|
|
DrawStringDecal({ float(ScreenWidth() / 2 - GetTextSize(bottomText).x / 2 * 3),float(ScreenHeight() - 140.f) }, bottomText, { 96,96,255 }, { 3,6 }); |
|
|
|
} |
|
|
|
} |
|
|
@ -1785,22 +2003,32 @@ void FaceBall::RunEnemyAI(Enemy& e,float fElapsedTime,int myIndex) { |
|
|
|
bool FaceBall::OnUserUpdate(float fElapsedTime) |
|
|
|
bool FaceBall::OnUserUpdate(float fElapsedTime) |
|
|
|
{ |
|
|
|
{ |
|
|
|
gameTimer += fElapsedTime; |
|
|
|
gameTimer += fElapsedTime; |
|
|
|
for (std::vector<Bullet>::iterator it = bullets.begin(); it != bullets.end(); ++it) { |
|
|
|
for (std::vector<Bullet>::iterator it = bullets.begin(); it != bullets.end();) { |
|
|
|
Bullet& b = *it; |
|
|
|
Bullet& b = *it; |
|
|
|
if (!b.Update(fElapsedTime)) { |
|
|
|
if (!b.Update(fElapsedTime)) { |
|
|
|
it=bullets.erase(it); |
|
|
|
it=bullets.erase(it); |
|
|
|
if (it == bullets.end()) { |
|
|
|
} |
|
|
|
break; |
|
|
|
else { |
|
|
|
} |
|
|
|
it++; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
for (int i = 0; i < enemies.size(); i++) { |
|
|
|
for (int i = 0; i < enemies.size(); i++) { |
|
|
|
Enemy& e = enemies[i]; |
|
|
|
Enemy& e = enemies[i]; |
|
|
|
|
|
|
|
e.Update(fElapsedTime); |
|
|
|
if (e.isLastHitTimerActive()) { |
|
|
|
if (e.isLastHitTimerActive()) { |
|
|
|
e.reduceLastHitTimer(fElapsedTime); |
|
|
|
e.reduceLastHitTimer(fElapsedTime); |
|
|
|
} |
|
|
|
} |
|
|
|
RunEnemyAI(e, fElapsedTime,i); |
|
|
|
RunEnemyAI(e, fElapsedTime,i); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for (std::vector<Powerup>::iterator it = powerups.begin(); it != powerups.end();) { |
|
|
|
|
|
|
|
Powerup& p = *it; |
|
|
|
|
|
|
|
if (!p.Update(fElapsedTime)) { |
|
|
|
|
|
|
|
it = powerups.erase(it); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
it++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
switch (mode) { |
|
|
|
switch (mode) { |
|
|
|
case GAME: { |
|
|
|
case GAME: { |
|
|
|
if (hp > 0) { |
|
|
|
if (hp > 0) { |
|
|
|