1
Fork 0
This repository has been archived on 2025-04-09. You can view files and clone it, but cannot push or open issues or pull requests.
beats-motor-client/src/Base.cpp
2013-04-17 23:50:23 +02:00

182 lines
4.6 KiB
C++

#include "Base.hpp"
#include "input.hpp"
#include <cmath>
#include <motor/basic/bullet_debug_drawer.hpp>
namespace games {
using namespace motor;
std::ostream& operator<<(std::ostream& out, Input::Mouse::Button const& rh){
using Button = Input::Mouse::Button;
switch(rh){
case Button::left: return out << "left";
case Button::middle: return out << "middle";
case Button::right: return out << "right";
case Button::wheeldown: return out << "downscroll";
case Button::wheelup: return out << "upscroll";
default: {
return out << rh;
}
}
}
Base::Base(int window_width_, int window_height_, std::shared_ptr<Base>& active_base_)
: window_width(window_width_)
, window_height(window_height_)
, active_base(active_base_)
{
physics_scene->used_shader = physics_scene->flat_shader;
}
Base::~Base()
{
resource_cache.free_all_resources();
motor::resource_cache.free_all_resources();
}
bool Base::has_ended(){
return false;
}
void Base::update(float const dt, Input input){
time += dt;
if(physics_update){
world.physics.update(dt, 10);
}
if(free_camera_mode){
handle_camera(dt, input);
}
world.ai.update(dt, input, world);
}
void Base::draw(){
try {
fbo.unbind();
moggle::gl::set_viewport(0, 0, window_width, window_height);
moggle::gl::set_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
moggle::gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
moggle::gl::enable(GL_DEPTH_TEST);
moggle::gl::enable(GL_BLEND);
moggle::gl::blend_function(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if(draw_physics_world){
physics_scene->camera = world.scene->camera;
for(auto mesh : world.physics.get_debug_draw_result(1 | 2 | 8)){
assert(mesh != nullptr);
auto const b = std::make_shared<Body>(mesh);
physics_scene->add(b);
}
physics_scene->draw();
physics_scene->remove_all_bodies();
}
if(!(draw_physics_world && draw_only_physics_world)){
world.scene->draw();
}
static constexpr bool print_screen = false;
if(print_screen){
std::vector<moggle::vector4<unsigned char>> pixels(window_width * window_height);
moggle::gl::clear_error();
glReadPixels(0, 0, window_width, window_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
moggle::gl::print_error();
for(int y = 0; y < window_height; ++y){
for(int x = 0; x < window_width; ++x){
for(int i = 0; i < 4; ++i){
std::cout << std::setw(3) << std::setfill('0') << size_t(pixels[y * window_height + x][i]) << ((i != 3) ? " " : "");
}
std::cout << "|";
}
std::cout << std::endl;
}
}
} catch (std::runtime_error& e){
CERR << "Something went wrong during drawing: " << e.what() << std::endl;
}
try {
moggle::gl::clear(GL_DEPTH_BUFFER_BIT);
world.hud->used_shader = world.hud->flat_shader;
world.hud->draw();
} catch (std::runtime_error& e){
CERR << "Something went wrong during drawing: " << e.what() << std::endl;
}
}
motor::Body* Base::raycast(moggle::vector2<float> const screen_position) const{
motor::Position const view = {0, 0, window_width, window_height};
motor::Position in = {screen_position[0], screen_position[1], 0.0, 1.f};
auto const near_point = world.scene->camera.unproject(in, view);
in[2] = 1.0f;
auto const far_point = world.scene->camera.unproject(in, view);
return world.physics.raycast(near_point, far_point);
}
void Base::handle_camera(const float dt, Input input)
{
SDL_ShowCursor(SDL_DISABLE);
float const distance = camera_speed * dt;
float const rotation = camera_rotation_speed * dt;
auto const move = [](Camera& p, Position const displacement){
p.set_position(p.get_position() + displacement);
};
Camera& b = world.scene->camera;
auto const m = inverse(b.get_rotation_matrix());
Position const down = m*Position{0, -distance, 0};
Position const up = m*Position{0, distance, 0};
Position const left = m*Position{-distance, 0, 0};
Position const right = m*Position{distance, 0, 0};
Position const backward = m*Position{0, 0, distance};
Position const forward = m*Position{0, 0, -distance};
if(input.keys_pressed[SDLK_w]){
move(b, forward);
}
if(input.keys_pressed[SDLK_s]){
move(b, backward);
}
if(input.keys_pressed[SDLK_d]){
move(b, right);
}
if(input.keys_pressed[SDLK_a]){
move(b, left);
}
if(input.keys_pressed[SDLK_t]){
move(b, up);
}
if(input.keys_pressed[SDLK_g]){
move(b, down);
}
b.add_pitch(-input.mouse.difference[1] * rotation);
b.add_yaw(-input.mouse.difference[0] * rotation);
input.mouse.position[0] = window_width/2;
input.mouse.position[1] = window_height/2;
SDL_WarpMouse(input.mouse.position[0], input.mouse.position[1]);
}
ResourceCache Base::resource_cache;
}