Compare commits

...

3 Commits

20 changed files with 375 additions and 31 deletions

View File

@ -171,6 +171,7 @@ if(BUILD_CLIENT)
src/game/window/window.cpp src/game/window/window.cpp
src/game/world/chunk_manager.cpp src/game/world/chunk_manager.cpp
src/game/world/local_player.cpp src/game/world/local_player.cpp
src/game/world/physic_manager.cpp
src/game/world/player_manager.cpp src/game/world/player_manager.cpp
src/game/world/remote_player.cpp src/game/world/remote_player.cpp
) )

View File

@ -38,6 +38,11 @@ Rect3D::Rect3D(float x, float y, float z, float width, float height, float depth
m_size({width, height, depth}) m_size({width, height, depth})
{} {}
Rect3D::Rect3D() :
m_pos(),
m_size()
{}
bool Rect3D::overlaps(const Rect3D& other) const { bool Rect3D::overlaps(const Rect3D& other) const {
return (m_pos[0]>=other.get_x() && m_pos[0]<=other.get_right()) || (get_right()>=other.get_x() && get_right()<=other.get_right()) || return (m_pos[0]>=other.get_x() && m_pos[0]<=other.get_right()) || (get_right()>=other.get_x() && get_right()<=other.get_right()) ||
(m_pos[1]<=other.get_y() && m_pos[1]>=other.get_bottom()) || (m_pos[1]>=other.get_y() && get_bottom()<=other.get_y()) || (m_pos[1]<=other.get_y() && m_pos[1]>=other.get_bottom()) || (m_pos[1]>=other.get_y() && get_bottom()<=other.get_y()) ||
@ -48,6 +53,10 @@ Rect3D Rect3D::constrained(const math::Vector3f& pos, const math::Vector3f& size
return Rect3D(std::min(m_pos[0], pos[0]), std::min(m_pos[1], pos[1]), std::min(m_pos[2], pos[2]), std::min(m_size[0], size[0]), std::min(m_size[1], size[1]), std::min(m_size[2], size[2])); return Rect3D(std::min(m_pos[0], pos[0]), std::min(m_pos[1], pos[1]), std::min(m_pos[2], pos[2]), std::min(m_size[0], size[0]), std::min(m_size[1], size[1]), std::min(m_size[2], size[2]));
} }
Rect3D Rect3D::moved(const math::Vector3f& offset) {
return Rect3D(m_pos+offset, m_size);
}
Rect3D Rect3D::with_center(const math::Vector3f& center, const math::Vector3f& size) { Rect3D Rect3D::with_center(const math::Vector3f& center, const math::Vector3f& size) {
return Rect3D(center+math::Vector3f{size[0], -size[1], -size[2]}/math::Vector3f{2, 2, 2}, size); return Rect3D(center+math::Vector3f{size[0], -size[1], -size[2]}/math::Vector3f{2, 2, 2}, size);
} }

View File

@ -32,15 +32,21 @@ namespace polygun::math {
public: public:
Rect3D(const math::Vector3f& pos, const math::Vector3f& size); Rect3D(const math::Vector3f& pos, const math::Vector3f& size);
Rect3D(float x, float y, float z, float width, float height, float depth); Rect3D(float x, float y, float z, float width, float height, float depth);
Rect3D();
~Rect3D() = default; ~Rect3D() = default;
void move(const Vector3f& offset) { m_pos+=offset; }
bool overlaps(const Rect3D& other) const; bool overlaps(const Rect3D& other) const;
Rect3D constrained(const math::Vector3f& pos, const math::Vector3f& size) const; Rect3D constrained(const math::Vector3f& pos, const math::Vector3f& size) const;
Rect3D moved(const math::Vector3f& offset);
void set_pos(const math::Vector3f& pos) { m_pos = pos; }
float get_x() const { return m_pos[0]; } float get_x() const { return m_pos[0]; }
float get_y() const { return m_pos[1]; } float get_y() const { return m_pos[1]; }
float get_z() const { return m_pos[2]; } float get_z() const { return m_pos[2]; }
const math::Vector3f& get_pos() const { return m_pos; }
float get_width() const { return m_size[0]; } float get_width() const { return m_size[0]; }
float get_height() const { return m_size[1]; } float get_height() const { return m_size[1]; }
float get_depth() const { return m_size[2]; } float get_depth() const { return m_size[2]; }

View File

@ -74,3 +74,11 @@ ChunkManagerBase::LoadedChunk& ChunkManagerBase::get_chunk_with_node(const math:
} }
return get_chunk(chunk_pos); return get_chunk(chunk_pos);
} }
polygun::math::Rect3D ChunkManagerBase::get_node_bbox(const math::Vector3i& node_pos) {
const uint16_t node_id = get_node(node_pos);
// TODO: Check node definition to see if node isn't solid
if(node_id==0)
return math::Rect3D(math::Vector3f(INFINITY), math::Vector3f(0));
return math::Rect3D(node_pos.convert<float>(), math::Vector3f(1));
}

View File

@ -28,7 +28,7 @@ SOFTWARE.
#include <vector> #include <vector>
#include <memory> #include <memory>
#include "common/math/vector.hpp" #include "common/math/rect3d.hpp"
#include "common/world/chunk.hpp" #include "common/world/chunk.hpp"
namespace polygun::world { namespace polygun::world {
@ -49,6 +49,7 @@ namespace polygun::world {
void fill_node(uint16_t node, math::Vector3i from, math::Vector3i to); void fill_node(uint16_t node, math::Vector3i from, math::Vector3i to);
uint16_t get_node(const math::Vector3i& node_pos); uint16_t get_node(const math::Vector3i& node_pos);
LoadedChunk& get_chunk_with_node(const math::Vector3i& node_pos); LoadedChunk& get_chunk_with_node(const math::Vector3i& node_pos);
math::Rect3D get_node_bbox(const math::Vector3i& node_pos);
virtual LoadedChunk& get_chunk(const math::Vector3i& pos) = 0; virtual LoadedChunk& get_chunk(const math::Vector3i& pos) = 0;

View File

@ -0,0 +1,60 @@
/*
PolyGun
Copyright (c) 2024 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "common/world/physic_manager_base.hpp"
#include "common/math/rect3d.hpp"
#include "common/world/chunk_manager_base.hpp"
using namespace polygun::world;
PhysicManagerBase::PhysicManagerBase(ChunkManagerBase* chunk_manager) :
m_chunk_manager(chunk_manager)
{}
bool PhysicManagerBase::is_free(const math::Rect3D& bbox) {
std::vector<math::Rect3D> bboxes;
get_surrounding_node_bboxes(bbox, bboxes);
for(const math::Rect3D& node_bbox : bboxes) {
if(bbox.overlaps(node_bbox))
return false;
}
return true;
}
void PhysicManagerBase::get_surrounding_node_bboxes(const math::Rect3D& bbox, std::vector<math::Rect3D>& output) {
const math::Vector3f& pos = bbox.get_pos();
for(int x = pos[0]; x<=pos[0]+bbox.get_width(); x++) {
for(int y = pos[1]; y<=pos[1]+bbox.get_height(); y++) {
for(int z = pos[2]; z<=pos[2]+bbox.get_depth(); z++) {
// FIXME: Use node definition to determine if node is solid
if(m_chunk_manager->get_node(math::Vector3i{x, y, z})==0)
output.push_back(math::Rect3D(math::Vector3f(INFINITY), math::Vector3f(0)));
else
output.push_back(math::Rect3D(x, y, z, 1, 1, 1));
}
}
}
}

View File

@ -0,0 +1,50 @@
/*
PolyGun
Copyright (c) 2024 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_WORLD_PHYSIC_MANAGER_BASE_HPP
#define POLYGUN_WORLD_PHYSIC_MANAGER_BASE_HPP
#include <vector>
namespace polygun::math {
class Rect3D;
}
namespace polygun::world {
class ChunkManagerBase;
class PhysicManagerBase {
public:
PhysicManagerBase(ChunkManagerBase* chunk_manager);
bool is_free(const math::Rect3D& bbox);
protected:
ChunkManagerBase* m_chunk_manager;
protected:
void get_surrounding_node_bboxes(const math::Rect3D& bbox, std::vector<math::Rect3D>& output);
};
}
#endif // POLYGUN_WORLD_PHYSIC_MANAGER_BASE_HPP

View File

@ -0,0 +1,55 @@
/*
PolyGun
Copyright (c) 2024 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_WORLD_PHYSICAL_OBJECT_HPP
#define POLYGUN_WORLD_PHYSICAL_OBJECT_HPP
#include "common/math/rect3d.hpp"
namespace polygun::world {
class PhysicalObject {
friend class PhysicManager;
public:
PhysicalObject(const math::Rect3D& initial_bbox) :
m_bbox(initial_bbox),
m_vel(),
m_acc(),
m_solid(true),
m_gravity(true)
{}
virtual ~PhysicalObject() = default;
void set_solid(bool solid) { m_solid = solid; }
void set_gravity(bool gravity) { m_gravity = gravity; }
protected:
math::Rect3D m_bbox;
math::Vector3f m_vel;
math::Vector3f m_acc;
bool m_solid;
bool m_gravity;
};
}
#endif // POLYGUN_WORLD_PHYSICAL_OBJECT_HPP

View File

@ -30,11 +30,10 @@ SOFTWARE.
using namespace polygun::world; using namespace polygun::world;
Player::Player(unsigned uuid, const math::Vector3f& initial_pos) : Player::Player(unsigned uuid, const math::Vector3f& initial_pos) :
PhysicalObject(math::Rect3D(initial_pos, math::Vector3f{0.75f, 1.8f, 0.75f})),
m_uuid(uuid), m_uuid(uuid),
m_mode(PlayerMode::PLAYER_MODE_NORMAL), m_mode(PlayerMode::PLAYER_MODE_NORMAL),
m_mode_changed(false), m_mode_changed(false),
m_pos(initial_pos),
m_vel(),
m_movement_front(), m_movement_front(),
m_movement_right(), m_movement_right(),
m_rot(0), m_rot(0),
@ -44,7 +43,7 @@ Player::Player(unsigned uuid, const math::Vector3f& initial_pos) :
#if defined(BUILD_CLIENT) #if defined(BUILD_CLIENT)
void Player::render(renderer::MeshRenderer* renderer, renderer::Mesh* player_mesh) { void Player::render(renderer::MeshRenderer* renderer, renderer::Mesh* player_mesh) {
renderer->rotate(math::Vector3f{0, 1, 0}, m_rot); renderer->rotate(math::Vector3f{0, 1, 0}, m_rot);
renderer->translate(m_pos); renderer->translate(get_position());
renderer->render(player_mesh, math::RGBAColorf{1, 0, 1, 1}); renderer->render(player_mesh, math::RGBAColorf{1, 0, 1, 1});
} }
#endif #endif

View File

@ -29,6 +29,7 @@ SOFTWARE.
#include <memory> #include <memory>
#include "common/math/vector.hpp" #include "common/math/vector.hpp"
#include "common/world/physical_object.hpp"
#include "common/world/player_mode.hpp" #include "common/world/player_mode.hpp"
#define MAX_PLAYER_NORMAL_MOVEMENT_SPEED (10.0f) #define MAX_PLAYER_NORMAL_MOVEMENT_SPEED (10.0f)
@ -42,7 +43,7 @@ namespace polygun::renderer {
#endif #endif
namespace polygun::world { namespace polygun::world {
class Player { class Player : public PhysicalObject {
public: public:
Player(unsigned uuid, const math::Vector3f& initial_pos); Player(unsigned uuid, const math::Vector3f& initial_pos);
virtual ~Player() = default; virtual ~Player() = default;
@ -54,18 +55,16 @@ namespace polygun::world {
void set_mode(PlayerMode mode); void set_mode(PlayerMode mode);
PlayerMode get_mode() const { return m_mode; } PlayerMode get_mode() const { return m_mode; }
bool has_mode_changed(); bool has_mode_changed();
void set_position(const math::Vector3f& pos) { m_pos = pos; } void set_position(const math::Vector3f& pos) { m_bbox.set_pos(pos); }
void set_rotation(float rot) { m_rot = rot; } void set_rotation(float rot) { m_rot = rot; }
unsigned get_uuid() const { return m_uuid; } unsigned get_uuid() const { return m_uuid; }
const math::Vector3f& get_position() const { return m_pos; } const math::Vector3f& get_position() const { return m_bbox.get_pos(); }
bool is_moving() const { return m_vel[0]!=0 || m_vel[1]!=0 || m_vel[2]!=0; } bool is_moving() const { return m_vel[0]!=0 || m_vel[1]!=0 || m_vel[2]!=0; }
protected: protected:
unsigned m_uuid; unsigned m_uuid;
PlayerMode m_mode; PlayerMode m_mode;
bool m_mode_changed; bool m_mode_changed;
math::Vector3f m_pos;
math::Vector3f m_vel;
math::Vector3f m_movement_front; math::Vector3f m_movement_front;
math::Vector3f m_movement_right; math::Vector3f m_movement_right;
float m_rot; float m_rot;

View File

@ -165,7 +165,7 @@ void EditmodeHUD::render() {
void EditmodeHUD::update_ray() { void EditmodeHUD::update_ray() {
const world::LocalPlayer& local_player = m_player_manager.get_master_local_player(); const world::LocalPlayer& local_player = m_player_manager.get_master_local_player();
m_ray.cast(local_player.get_position(), local_player.get_view_direction()); m_ray.cast(local_player.get_eye_position(), local_player.get_view_direction());
std::stringstream stream; std::stringstream stream;
if(m_ray.is_hit()) { if(m_ray.is_hit()) {
const math::Vector3i& ray_target = m_ray.get_hit_node(); const math::Vector3i& ray_target = m_ray.get_hit_node();
@ -208,6 +208,9 @@ void EditmodeHUD::on_switch() {
update_ray(); update_ray();
update_position_text(); update_position_text();
m_player_manager.get_master_local_player().set_solid(false);
m_player_manager.get_master_local_player().set_gravity(false);
} }
void EditmodeHUD::open_context_toolbox() { void EditmodeHUD::open_context_toolbox() {

View File

@ -25,6 +25,7 @@ SOFTWARE.
#include "game/hud/normal_hud.hpp" #include "game/hud/normal_hud.hpp"
#include "game/engine/engine.hpp" #include "game/engine/engine.hpp"
#include "game/world/player_manager.hpp"
using namespace polygun::hud; using namespace polygun::hud;
@ -36,4 +37,7 @@ void NormalHUD::render() {}
void NormalHUD::on_switch() { void NormalHUD::on_switch() {
m_engine->get_gui_master().get_component_by_id<gui::Container>("container_editmode_hud")->set_hidden(true); m_engine->get_gui_master().get_component_by_id<gui::Container>("container_editmode_hud")->set_hidden(true);
m_player_manager.get_master_local_player().set_solid(true);
m_player_manager.get_master_local_player().set_gravity(true);
} }

View File

@ -91,11 +91,12 @@ void GameSessionScreen::begin() {
m_texture_atlas = new engine::TextureAtlas(m_engine->get_master_renderer(), *m_content_registry, *m_resource_manager); m_texture_atlas = new engine::TextureAtlas(m_engine->get_master_renderer(), *m_content_registry, *m_resource_manager);
m_chunk_manager.reset(new world::ChunkManager(m_engine, *m_texture_atlas)); m_chunk_manager.reset(new world::ChunkManager(m_engine, *m_texture_atlas));
m_player_manager.reset(new world::PlayerManager(m_engine, *m_chunk_manager)); m_player_manager.reset(new world::PlayerManager(m_engine, *m_chunk_manager));
m_physic_manager.reset(new world::PhysicManager(m_chunk_manager.get()));
m_engine->get_mesh_renderer()->invalidate_cache(); m_engine->get_mesh_renderer()->invalidate_cache();
m_engine->get_gui_master().load_from_file("res/gui/game_session.xml", m_engine); gui::GUIMaster& gui_master = m_engine->get_gui_master();
switch_hud(world::PlayerMode::PLAYER_MODE_NORMAL); gui_master.load_from_file("res/gui/game_session.xml", m_engine);
m_player_manager->set_chat(m_current_hud->get_chat()); m_player_manager->set_chat(gui_master.get_component_by_id<gui::Chat>("chat"));
m_engine->get_window()->grab_mouse(true); m_engine->get_window()->grab_mouse(true);
@ -112,7 +113,7 @@ void GameSessionScreen::render() {
mesh_renderer->set_3d_rendering_mode(true); mesh_renderer->set_3d_rendering_mode(true);
m_chunk_manager->render(); m_chunk_manager->render();
m_player_manager->render_players(); m_player_manager->render_players();
if(!m_game_paused) if(!m_game_paused && m_current_hud)
m_current_hud->render(); m_current_hud->render();
break; break;
} }
@ -132,7 +133,7 @@ void GameSessionScreen::update(double delta) {
case GameState::GAME_STATE_RUNNING: case GameState::GAME_STATE_RUNNING:
if((m_engine->get_window()->is_mouse_grabbed() || m_game_paused) && m_player_manager->get_master_local_player().get_controller()->is_control_pressed(control::Control::CONTROL_PAUSE)) if((m_engine->get_window()->is_mouse_grabbed() || m_game_paused) && m_player_manager->get_master_local_player().get_controller()->is_control_pressed(control::Control::CONTROL_PAUSE))
toggle_pause(); toggle_pause();
if(!m_game_paused) if(!m_game_paused && m_current_hud)
m_current_hud->update(delta); m_current_hud->update(delta);
m_texture_atlas->update(); m_texture_atlas->update();
m_player_manager->update_controllers(); m_player_manager->update_controllers();
@ -141,6 +142,7 @@ void GameSessionScreen::update(double delta) {
if(m_player_manager->get_master_local_player().has_mode_changed()) if(m_player_manager->get_master_local_player().has_mode_changed())
switch_hud(m_player_manager->get_master_local_player().get_mode()); switch_hud(m_player_manager->get_master_local_player().get_mode());
m_chunk_manager->update_chunks(); m_chunk_manager->update_chunks();
m_physic_manager->update(delta);
default: default:
break; break;
} }
@ -212,7 +214,7 @@ void GameSessionScreen::connection_thread_func() {
m_content_registry->set_network_manager(&network_manager); m_content_registry->set_network_manager(&network_manager);
m_player_manager->set_network_manager(&network_manager); m_player_manager->set_network_manager(&network_manager);
m_chunk_manager->set_network_manager(&network_manager); m_chunk_manager->set_network_manager(&network_manager);
m_current_hud->get_chat()->set_network_manager(&network_manager); m_engine->get_gui_master().get_component_by_id<gui::Chat>("chat")->set_network_manager(&network_manager);
polygun::network::NetworkPacket handshake = network_manager.create_packet(polygun::network::NetworkPacketFlag::FLAG_RELIABLE, polygun::network::NetworkPacketID::PACKET_HANDSHAKE); polygun::network::NetworkPacket handshake = network_manager.create_packet(polygun::network::NetworkPacketFlag::FLAG_RELIABLE, polygun::network::NetworkPacketID::PACKET_HANDSHAKE);
polygun::network::NetworkPacket packet; polygun::network::NetworkPacket packet;
handshake.write(m_player_nick); handshake.write(m_player_nick);
@ -251,6 +253,7 @@ void GameSessionScreen::connection_thread_func() {
packet.read(uuid); packet.read(uuid);
LOG_INFO("Your player UUID is %d", uuid); LOG_INFO("Your player UUID is %d", uuid);
m_player_manager->add_local_player(uuid, std::make_unique<control::KeyboardController>(m_engine->get_window()), std::make_unique<control::MouseCameraController>()); m_player_manager->add_local_player(uuid, std::make_unique<control::KeyboardController>(m_engine->get_window()), std::make_unique<control::MouseCameraController>());
m_physic_manager->add_physical_object(&m_player_manager->get_master_local_player());
uint16_t registered_node_count; uint16_t registered_node_count;
packet.read(registered_node_count); packet.read(registered_node_count);

View File

@ -39,6 +39,7 @@ SOFTWARE.
#include "game/hud/normal_hud.hpp" #include "game/hud/normal_hud.hpp"
#include "game/world/chunk_manager.hpp" #include "game/world/chunk_manager.hpp"
#include "game/world/player_manager.hpp" #include "game/world/player_manager.hpp"
#include "game/world/physic_manager.hpp"
namespace polygun::screens { namespace polygun::screens {
enum GameState { enum GameState {
@ -73,6 +74,7 @@ namespace polygun::screens {
engine::TextureAtlas* m_texture_atlas; engine::TextureAtlas* m_texture_atlas;
std::unique_ptr<world::ChunkManager> m_chunk_manager; std::unique_ptr<world::ChunkManager> m_chunk_manager;
std::unique_ptr<world::PlayerManager> m_player_manager; std::unique_ptr<world::PlayerManager> m_player_manager;
std::unique_ptr<world::PhysicManager> m_physic_manager;
std::unique_ptr<std::thread> m_connection_thread; std::unique_ptr<std::thread> m_connection_thread;
#if defined(BUILD_SERVER) #if defined(BUILD_SERVER)
std::unique_ptr<std::thread> m_local_server_thread; std::unique_ptr<std::thread> m_local_server_thread;

View File

@ -44,6 +44,7 @@ LocalPlayer::LocalPlayer(unsigned uuid, const math::Vector3f& initial_pos, std::
m_pitch(0), m_pitch(0),
m_front({0.0f, 0.0f, -1.0f}), m_front({0.0f, 0.0f, -1.0f}),
m_up({0.0f, 1.0f, 0.0f}), m_up({0.0f, 1.0f, 0.0f}),
m_eye_pos(),
m_prev_screen_size(), m_prev_screen_size(),
m_first_update(true), m_first_update(true),
m_prev_position_send(std::chrono::steady_clock::now()) m_prev_position_send(std::chrono::steady_clock::now())
@ -59,17 +60,21 @@ void LocalPlayer::update(float delta) {
m_vel-=math::Vector3f{m_movement_right[0], 0, m_movement_right[2]}*acceleration; m_vel-=math::Vector3f{m_movement_right[0], 0, m_movement_right[2]}*acceleration;
if(m_controller->is_control_held(control::Control::CONTROL_RIGHT)) if(m_controller->is_control_held(control::Control::CONTROL_RIGHT))
m_vel+=math::Vector3f{m_movement_right[0], 0, m_movement_right[2]}*acceleration; m_vel+=math::Vector3f{m_movement_right[0], 0, m_movement_right[2]}*acceleration;
if(m_controller->is_control_held(control::Control::CONTROL_JUMP)) if(m_gravity) {
m_vel+=math::Vector3f{0, acceleration, 0}; if(m_vel[1]==0 && m_controller->is_control_held(control::Control::CONTROL_JUMP))
if(m_controller->is_control_held(control::Control::CONTROL_CROUCH)) m_acc[1] = 3.0f;
m_vel+=math::Vector3f{0, -acceleration, 0}; }
else {
if(m_controller->is_control_held(control::Control::CONTROL_JUMP))
m_vel+=math::Vector3f{0, acceleration, 0};
if(m_controller->is_control_held(control::Control::CONTROL_CROUCH))
m_vel+=math::Vector3f{0, -acceleration, 0};
m_vel[1] = std::max(std::min(m_vel[1], MAX_PLAYER_NORMAL_MOVEMENT_SPEED), -MAX_PLAYER_NORMAL_MOVEMENT_SPEED);
}
m_vel[0] = std::max(std::min(m_vel[0], MAX_PLAYER_NORMAL_MOVEMENT_SPEED), -MAX_PLAYER_NORMAL_MOVEMENT_SPEED); m_vel[0] = std::max(std::min(m_vel[0], MAX_PLAYER_NORMAL_MOVEMENT_SPEED), -MAX_PLAYER_NORMAL_MOVEMENT_SPEED);
m_vel[1] = std::max(std::min(m_vel[1], MAX_PLAYER_NORMAL_MOVEMENT_SPEED), -MAX_PLAYER_NORMAL_MOVEMENT_SPEED);
m_vel[2] = std::max(std::min(m_vel[2], MAX_PLAYER_NORMAL_MOVEMENT_SPEED), -MAX_PLAYER_NORMAL_MOVEMENT_SPEED); m_vel[2] = std::max(std::min(m_vel[2], MAX_PLAYER_NORMAL_MOVEMENT_SPEED), -MAX_PLAYER_NORMAL_MOVEMENT_SPEED);
m_pos+=m_vel*delta;
const math::Vector2f offset = m_camera_controller->get_offset()*engine::GameConfig::get().m_mouse_sensitivity; const math::Vector2f offset = m_camera_controller->get_offset()*engine::GameConfig::get().m_mouse_sensitivity;
m_rot+=offset[0]; m_rot+=offset[0];
m_pitch+=offset[1]; m_pitch+=offset[1];
@ -97,7 +102,7 @@ void LocalPlayer::update(float delta) {
std::chrono::duration<double> interval = tm-m_prev_position_send; std::chrono::duration<double> interval = tm-m_prev_position_send;
if(interval.count()>=1.0/ENGINE_SPS) { if(interval.count()>=1.0/ENGINE_SPS) {
network::NetworkPacket packet = m_network_manager->create_packet(network::NetworkPacketFlag::FLAG_NONE, network::NetworkPacketID::PACKET_POSITION); network::NetworkPacket packet = m_network_manager->create_packet(network::NetworkPacketFlag::FLAG_NONE, network::NetworkPacketID::PACKET_POSITION);
packet.write(m_pos); packet.write(get_position());
m_network_manager->send_packet(packet); m_network_manager->send_packet(packet);
m_prev_position_send = tm; m_prev_position_send = tm;
} }
@ -134,7 +139,10 @@ void LocalPlayer::update_motion_vectors() {
m_movement_right = m_movement_front.cross(m_up).normalize(); m_movement_right = m_movement_front.cross(m_up).normalize();
m_view.look_at(m_pos, m_pos+m_front, m_up); m_eye_pos[0] = get_position()[0]+m_bbox.get_width()/2;
m_eye_pos[1] = get_position()[1]+m_bbox.get_height()-0.2f;
m_eye_pos[2] = get_position()[2]+m_bbox.get_depth()/2;
m_view.look_at(m_eye_pos, m_eye_pos+m_front, m_up);
m_chunk_manager.on_local_player_move(*this); m_chunk_manager.on_local_player_move(*this);
} }

View File

@ -53,6 +53,7 @@ namespace polygun::world {
control::Controller* get_controller() { return m_controller.get(); } control::Controller* get_controller() { return m_controller.get(); }
control::CameraController* get_camera_controller() { return m_camera_controller.get(); } control::CameraController* get_camera_controller() { return m_camera_controller.get(); }
const math::Vector3f& get_view_direction() const { return m_front; } const math::Vector3f& get_view_direction() const { return m_front; }
const math::Vector3f& get_eye_position() const { return m_eye_pos; }
private: private:
std::unique_ptr<control::Controller> m_controller; std::unique_ptr<control::Controller> m_controller;
@ -62,6 +63,7 @@ namespace polygun::world {
float m_pitch; float m_pitch;
math::Vector3f m_front; math::Vector3f m_front;
math::Vector3f m_up; math::Vector3f m_up;
math::Vector3f m_eye_pos;
math::Vector3i m_prev_screen_size; math::Vector3i m_prev_screen_size;
bool m_first_update; bool m_first_update;
std::chrono::time_point<std::chrono::steady_clock> m_prev_position_send; std::chrono::time_point<std::chrono::steady_clock> m_prev_position_send;

View File

@ -0,0 +1,83 @@
/*
PolyGun
Copyright (c) 2024 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "game/world/physic_manager.hpp"
#include "game/world/chunk_manager.hpp"
#include "common/world/physical_object.hpp"
using namespace polygun::world;
PhysicManager::PhysicManager(ChunkManagerBase* chunk_manager) :
PhysicManagerBase(chunk_manager)
{}
void PhysicManager::update(float delta) {
acquire();
// Collision against map
for(PhysicalObject* physical_object : m_physical_objects) {
if(!physical_object->m_solid) {
physical_object->m_bbox.move(physical_object->m_vel*delta);
continue;
}
if(physical_object->m_gravity) {
if(physical_object->m_acc[1]>PHYSIC_MANAGER_GRAVITY_ACCEL)
physical_object->m_acc[1]-=0.2f;
if(physical_object->m_vel[1]>PHYSIC_MANAGER_GRAVITY)
physical_object->m_vel[1]+=physical_object->m_acc[1];
}
if(!is_free(physical_object->m_bbox))
physical_object->m_bbox.move(math::Vector3f{0, 0.1f, 0});
const math::Vector3f x_offset{physical_object->m_vel[0]*delta, 0.0f, 0.0f};
const math::Rect3D x_dest_bbox = physical_object->m_bbox.moved(x_offset);
if(is_free(x_dest_bbox))
physical_object->m_bbox.move(x_offset);
else
physical_object->m_vel[0] = 0;
const math::Vector3f y_offset{0.0f, physical_object->m_vel[1]*delta, 0.0f};
const math::Rect3D y_dest_bbox = physical_object->m_bbox.moved(y_offset);
if(is_free(y_dest_bbox))
physical_object->m_bbox.move(y_offset);
else
physical_object->m_vel[1] = 0;
const math::Vector3f z_offset{0.0f, 0.0f, physical_object->m_vel[2]*delta};
const math::Rect3D z_dest_bbox = physical_object->m_bbox.moved(z_offset);
if(is_free(z_dest_bbox))
physical_object->m_bbox.move(z_offset);
else
physical_object->m_vel[2] = 0;
}
release();
}
void PhysicManager::add_physical_object(PhysicalObject* physical_object) {
acquire();
m_physical_objects.push_back(physical_object);
release();
}

View File

@ -0,0 +1,51 @@
/*
PolyGun
Copyright (c) 2024 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_WORLD_PHYSIC_MANAGER_HPP
#define POLYGUN_WORLD_PHYSIC_MANAGER_HPP
#include "common/world/physic_manager_base.hpp"
#include "common/thread_safe.hpp"
#include <vector>
#define PHYSIC_MANAGER_GRAVITY -35.0f
#define PHYSIC_MANAGER_GRAVITY_ACCEL -3.0f
namespace polygun::world {
class PhysicalObject;
class PhysicManager final : public PhysicManagerBase, public utils::ThreadSafe {
public:
PhysicManager(ChunkManagerBase* chunk_manager);
void update(float delta);
void add_physical_object(PhysicalObject* physical_object);
private:
std::vector<PhysicalObject*> m_physical_objects;
};
}
#endif // POLYGUN_WORLD_PHYSIC_MANAGER_HPP

View File

@ -39,10 +39,10 @@ static const std::vector<float> player_mesh_vertices = {
0.75f, 0.0f, 0.0f, 0.75f, 0.0f, 0.0f,
0.75f, 0.0f, -0.75f, 0.75f, 0.0f, -0.75f,
0.0f, 0.0f, -0.75f, 0.0f, 0.0f, -0.75f,
0.0f, 2.0f, -0.75f, 0.0f, 1.8f, -0.75f,
0.0f, 2.0f, 0.0f, 0.0f, 1.8f, 0.0f,
0.75f, 2.0f, 0.0f, 0.75f, 1.8f, 0.0f,
0.75f, 2.0f, -0.75f 0.75f, 1.8f, -0.75f
}; };
static const std::vector<unsigned> player_mesh_indices = { static const std::vector<unsigned> player_mesh_indices = {
0,1,2,2,0,3, 0,1,2,2,0,3,
@ -169,7 +169,7 @@ void PlayerManager::update_controllers() {
} }
void PlayerManager::add_local_player(unsigned uuid, std::unique_ptr<control::Controller> controller, std::unique_ptr<control::CameraController> camera_controller) { void PlayerManager::add_local_player(unsigned uuid, std::unique_ptr<control::Controller> controller, std::unique_ptr<control::CameraController> camera_controller) {
m_local_players.push_back(std::make_unique<LocalPlayer>(uuid, math::Vector3f{0, 0, 0}, std::move(controller), std::move(camera_controller), m_network_manager, m_chunk_manager)); m_local_players.push_back(std::make_unique<LocalPlayer>(uuid, math::Vector3f{5, 20, 5}, std::move(controller), std::move(camera_controller), m_network_manager, m_chunk_manager));
} }
Player* PlayerManager::find_player_by_uuid(unsigned uuid) { Player* PlayerManager::find_player_by_uuid(unsigned uuid) {

View File

@ -43,6 +43,6 @@ void Client::update_activity() {
void Client::serialize(network::NetworkPacket& packet) const { void Client::serialize(network::NetworkPacket& packet) const {
packet.write(m_uuid); packet.write(m_uuid);
packet.write(m_nick); packet.write(m_nick);
packet.write(m_pos); packet.write(get_position());
packet.write(m_rot); packet.write(m_rot);
} }