#include "Player.hpp" namespace MC::Entities { void Player::update(const Time& time, GFX::Window& window, GFX::Camera& camera, World::World& world) { auto r = window.mouse_delta(); auto key = [&](Int k) -> Real { return window.key(k, GLFW_PRESS); }; Real x = key(GLFW_KEY_D) - key(GLFW_KEY_A); Real y = key(GLFW_KEY_SPACE) - key(GLFW_KEY_LEFT_SHIFT); Real z = key(GLFW_KEY_S) - key(GLFW_KEY_W); Real boost = key(GLFW_KEY_LEFT_CONTROL) * 75.0f; auto move_speed = (20.0f + boost) * time.delta(); auto rotation_speed = 0.1f; auto direction = m_transform.right() * x + Vec3(0, y, 0) + m_transform.forward() * z; auto position = m_transform.position() + direction * move_speed; auto collisions = colliding_terrain(position, world); if (collisions.empty()) move_to(position); rotate({r.y() * rotation_speed, r.x() * rotation_speed, 0.0f}); update_camera_position(camera); } void Player::move(Position::WorldOffset by) { m_transform.position() += by; } void Player::rotate(Rotation by) { m_transform.rotation() += by; m_transform.rotation().pitch() = std::clamp(m_transform.rotation().pitch(), -89.0, 89.0); } void Player::move_to(Position::World to) { m_transform.position() = to; } void Player::rotate_to(Rotation to) { m_transform.rotation() = to; } AABB Player::bounds() const { return bounding_box_for_position(m_transform.position()); } void Player::update_camera_position(GFX::Camera& camera) { auto camera_position = m_transform.position(); camera_position.y() += 1.5; camera.set_position(camera_position); camera.set_angles(m_transform.rotation()); } FlexArray Player::colliding_terrain( Position::World new_position, World::World& world ) { FlexArray colliding_blocks; auto corners = bounding_box_for_position(new_position).corners(); for (auto corner : corners) { auto block_position = Position::World(corner).round_to_block(); if (block_position.y() < 0 || block_position.y() >= World::Chunk::Height) continue; auto block = world.block_at(block_position); if (!block.empty()) { colliding_blocks.push_back(World::Chunk::block_bounds(block_position.to_local())); } } return colliding_blocks; } AABB Player::bounding_box_for_position(Position::World position) { Vec3 box_start = { position.x() - s_bounds.max.x() / 2, position.y(), position.z() - s_bounds.max.z() / 2, }; return s_bounds.offset(box_start); } }