161 lines
5.1 KiB
C++
161 lines
5.1 KiB
C++
#include "math/float_types.hpp"
|
|
#include "math/transform.hpp"
|
|
|
|
#include "platform/graphics_primitive.hpp"
|
|
#include "platform/font.hpp"
|
|
|
|
#include "physics/particle.hpp"
|
|
|
|
#include "demo/ballistics.hpp"
|
|
|
|
namespace demo {
|
|
|
|
void ballistics::projectile::draw(ta_parameter_writer& writer, const mat4x4& trans)
|
|
{
|
|
const vec3 color(1.0, 1.0, 1.0);
|
|
draw_cube(writer, trans * translate(particle.position) * scale(1.f), color);
|
|
}
|
|
|
|
void ballistics::init()
|
|
{
|
|
current_projectile_type = projectile_type::ARTILLERY;
|
|
|
|
for (int i = 0; i < max_projectiles; i++) {
|
|
projectiles[i].type = projectile_type::NONE;
|
|
}
|
|
}
|
|
|
|
void ballistics::a()
|
|
{
|
|
projectile * projectile;
|
|
|
|
int i;
|
|
for (i = 0; i < max_projectiles; i++) {
|
|
projectile = &projectiles[i];
|
|
if (projectile->type == projectile_type::NONE)
|
|
break;
|
|
}
|
|
|
|
if (i >= max_projectiles)
|
|
return; // too many projectiles
|
|
|
|
switch (current_projectile_type) {
|
|
case projectile_type::PISTOL:
|
|
projectile->particle.inverse_mass = 1.0f / 2.0f;
|
|
projectile->particle.velocity = vec3(0.0f, 0.0f, 35.0f);
|
|
projectile->particle.acceleration = vec3(0.0f, -1.0f, 0.0f);
|
|
projectile->particle.damping = 0.99f;
|
|
break;
|
|
case projectile_type::ARTILLERY:
|
|
projectile->particle.inverse_mass = 1.0f / 1.0f;
|
|
projectile->particle.velocity = vec3(0.0f, 30.0f, 40.0f);
|
|
projectile->particle.acceleration = vec3(0.0f, -20.0f, 0.0f);
|
|
projectile->particle.damping = 0.99f;
|
|
break;
|
|
case projectile_type::FIREBALL:
|
|
projectile->particle.inverse_mass = 1.0f / 10.0f;
|
|
projectile->particle.velocity = vec3(0.0f, 0.0f, 10.0f);
|
|
projectile->particle.acceleration = vec3(0.0f, 0.6f, 0.0f);
|
|
projectile->particle.damping = 0.99f;
|
|
break;
|
|
case projectile_type::LASER:
|
|
projectile->particle.inverse_mass = 1.0f / 0.1f;
|
|
projectile->particle.velocity = vec3(0.0f, 0.0f, 100.0f);
|
|
projectile->particle.acceleration = vec3(0.0f, 0.0f, 0.0f);
|
|
projectile->particle.damping = 0.99f;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
projectile->particle.position = vec3(0.0f, 1.5f, 0.0f);
|
|
projectile->start_time = tick;
|
|
projectile->type = current_projectile_type;
|
|
//projectile->particle.clear_accumulator(); FIXME
|
|
projectile->particle.force_accum = vec3(0, 0, 0);
|
|
}
|
|
|
|
void ballistics::x()
|
|
{
|
|
switch (current_projectile_type) {
|
|
default: [[fallthrough]];
|
|
case projectile_type::PISTOL: current_projectile_type = projectile_type::ARTILLERY; break;
|
|
case projectile_type::ARTILLERY: current_projectile_type = projectile_type::FIREBALL; break;
|
|
case projectile_type::FIREBALL: current_projectile_type = projectile_type::LASER; break;
|
|
case projectile_type::LASER: current_projectile_type = projectile_type::PISTOL; break;
|
|
}
|
|
}
|
|
|
|
void ballistics::update()
|
|
{
|
|
float duration = 1.0f / 60.0f;
|
|
tick += 1;
|
|
|
|
for (int i = 0; i < max_projectiles; i++) {
|
|
projectile * projectile = &projectiles[i];
|
|
if (projectile->type == projectile_type::NONE)
|
|
continue;
|
|
|
|
projectile->particle.integrate(duration);
|
|
|
|
if (projectile->particle.position.z > 200.0f ||
|
|
projectile->particle.position.y < 0.0f ||
|
|
projectile->start_time < tick - 600) {
|
|
projectile->type = projectile_type::NONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ballistics::draw_hud(ta_parameter_writer& writer)
|
|
{
|
|
const int title_length = 16;
|
|
const int title_width_2 = (font::ter_u12n.hori_advance * title_length) >> 1;
|
|
const int framebuffer_width_2 = framebuffer::framebuffer.px_width >> 1;
|
|
const int x = framebuffer_width_2 - title_width_2;
|
|
vec3 center_p = vec3(x, 5, 10);
|
|
|
|
font::ter_u12n.global(writer);
|
|
font::ter_u12n.draw_string(writer, center_p, "demo: ballistics", 0xffffffff);
|
|
|
|
const char * label;
|
|
switch (current_projectile_type) {
|
|
default: [[fallthrough]];
|
|
case projectile_type::PISTOL: label = "pistol"; break;
|
|
case projectile_type::ARTILLERY: label = "artillery"; break;
|
|
case projectile_type::FIREBALL: label = "fireball"; break;
|
|
case projectile_type::LASER: label = "laser"; break;
|
|
}
|
|
|
|
vec3 p(5, 10, 10);
|
|
font::ter_u12n.draw_string(writer, p, "projectile_type:", 0xffffffff);
|
|
p.x += font::ter_u12n.hori_advance * 17;
|
|
font::ter_u12n.draw_string(writer, p, label, 0xffffffff);
|
|
}
|
|
|
|
void ballistics::draw(ta_parameter_writer& writer, const mat4x4& trans)
|
|
{
|
|
// punch through
|
|
draw_hud(writer);
|
|
|
|
writer.append<ta_global_parameter::end_of_list>() =
|
|
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
|
|
|
// opaque
|
|
|
|
draw_axis(writer, trans * scale(5.f));
|
|
|
|
draw_grid(writer, trans * translate(vec3(0, 0, 50)) * scale(vec3(20, 10, 100)));
|
|
|
|
for (int i = 0; i < max_projectiles; i++) {
|
|
projectile * projectile = &projectiles[i];
|
|
if (projectile->type == projectile_type::NONE)
|
|
continue;
|
|
|
|
projectile->draw(writer, trans);
|
|
}
|
|
|
|
writer.append<ta_global_parameter::end_of_list>() =
|
|
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
|
|
}
|
|
}
|