#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(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(para_control::para_type::end_of_list); } }