Node editing improvements
This commit is contained in:
parent
7fea96083d
commit
cf7b56167b
@ -4,8 +4,8 @@ in vec2 out_uv;
|
|||||||
|
|
||||||
out vec4 out_color;
|
out vec4 out_color;
|
||||||
|
|
||||||
uniform sampler2D uniform_texture_num;
|
uniform vec4 uniform_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
out_color = texture(uniform_texture_num, out_uv) * vec4(1.0, 1.0, 1.0, 0.3);
|
out_color = uniform_color;
|
||||||
}
|
}
|
||||||
|
@ -49,12 +49,18 @@ namespace polygun::control {
|
|||||||
m_place_node_req = false;
|
m_place_node_req = false;
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
bool is_dig_node_req() {
|
||||||
|
const bool temp = m_dig_node_req;
|
||||||
|
m_dig_node_req = false;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void update(const window::Event& event) = 0;
|
virtual void update(const window::Event& event) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
math::Vector2f m_offset;
|
math::Vector2f m_offset;
|
||||||
bool m_place_node_req;
|
bool m_place_node_req;
|
||||||
|
bool m_dig_node_req;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ void MouseCameraController::update(const window::Event& event) {
|
|||||||
switch(event.m_type) {
|
switch(event.m_type) {
|
||||||
case window::EventType::EVENT_TYPE_MOUSE_BUTTON_DOWN:
|
case window::EventType::EVENT_TYPE_MOUSE_BUTTON_DOWN:
|
||||||
m_place_node_req = event.m_data.m_mouse_event.m_button==window::MouseButton::MOUSE_BUTTON_RIGHT;
|
m_place_node_req = event.m_data.m_mouse_event.m_button==window::MouseButton::MOUSE_BUTTON_RIGHT;
|
||||||
|
m_dig_node_req = event.m_data.m_mouse_event.m_button==window::MouseButton::MOUSE_BUTTON_LEFT;
|
||||||
break;
|
break;
|
||||||
case window::EventType::EVENT_TYPE_MOUSE_MOVE:
|
case window::EventType::EVENT_TYPE_MOUSE_MOVE:
|
||||||
m_offset[0] = event.m_data.m_mouse_event.m_relative_x;
|
m_offset[0] = event.m_data.m_mouse_event.m_relative_x;
|
||||||
|
@ -32,17 +32,30 @@ SOFTWARE.
|
|||||||
|
|
||||||
using namespace polygun::engine;
|
using namespace polygun::engine;
|
||||||
|
|
||||||
Ray::Ray(world::ChunkManager& chunk_manager, const math::Vector3f& source, const math::Vector3f& direction) :
|
Ray::Ray(world::ChunkManager& chunk_manager) :
|
||||||
m_chunk_manager(chunk_manager),
|
m_chunk_manager(chunk_manager)
|
||||||
m_source(source),
|
|
||||||
m_direction(direction)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
polygun::math::Vector3f Ray::cast() {
|
void Ray::cast(const math::Vector3f& source, const math::Vector3f& direction) {
|
||||||
math::Vector3f current_position = m_source;
|
math::Vector3f current_position = source;
|
||||||
const math::Vector3f step = m_direction*RAY_STEP;
|
const math::Vector3f step = direction*RAY_STEP;
|
||||||
while(m_chunk_manager.get_node(math::Vector3i{static_cast<int>(current_position[0]), static_cast<int>(current_position[1]), static_cast<int>(current_position[2])})==0 && m_source.distance(current_position)<8) {
|
while(m_chunk_manager.get_node(math::Vector3i{static_cast<int>(current_position[0]), static_cast<int>(current_position[1]), static_cast<int>(current_position[2])})==0 && (m_hit = source.distance(current_position)<8)) {
|
||||||
current_position+=step;
|
current_position+=step;
|
||||||
}
|
}
|
||||||
return current_position-step;
|
if(m_hit) {
|
||||||
|
m_hit_node = current_position.convert<int>();
|
||||||
|
const math::Vector3f node_center{m_hit_node[0]+0.5f, m_hit_node[1]+0.5f, m_hit_node[2]+0.5f};
|
||||||
|
const math::Vector3f diff = current_position-step-node_center;
|
||||||
|
unsigned char max_index = 0;
|
||||||
|
float max_value = std::abs(diff[0]);
|
||||||
|
for(unsigned char i = 1; i<3; i++) {
|
||||||
|
const float current_value = std::abs(diff[i]);
|
||||||
|
if(current_value>max_value) {
|
||||||
|
max_index = i;
|
||||||
|
max_value = current_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_next_node = m_hit_node;
|
||||||
|
m_next_node[max_index]+=1-2*(diff[max_index]<0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,15 +35,20 @@ namespace polygun::world {
|
|||||||
namespace polygun::engine {
|
namespace polygun::engine {
|
||||||
class Ray final {
|
class Ray final {
|
||||||
public:
|
public:
|
||||||
Ray(world::ChunkManager& chunk_manager, const math::Vector3f& source, const math::Vector3f& direction);
|
Ray(world::ChunkManager& chunk_manager);
|
||||||
~Ray() = default;
|
~Ray() = default;
|
||||||
|
|
||||||
math::Vector3f cast();
|
void cast(const math::Vector3f& source, const math::Vector3f& direction);
|
||||||
|
|
||||||
|
bool is_hit() const { return m_hit; }
|
||||||
|
const math::Vector3i& get_hit_node() const { return m_hit_node; }
|
||||||
|
const math::Vector3i& get_next_node() const { return m_next_node; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
world::ChunkManager& m_chunk_manager;
|
world::ChunkManager& m_chunk_manager;
|
||||||
math::Vector3f m_source;
|
bool m_hit;
|
||||||
math::Vector3f m_direction;
|
math::Vector3i m_hit_node;
|
||||||
|
math::Vector3i m_next_node;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include "game/engine/engine.hpp"
|
#include "game/engine/engine.hpp"
|
||||||
#include "game/engine/content_registry.hpp"
|
#include "game/engine/content_registry.hpp"
|
||||||
#include "game/engine/ray.hpp"
|
|
||||||
#include "game/engine/resource_manager.hpp"
|
#include "game/engine/resource_manager.hpp"
|
||||||
#include "game/gui/image_gallery.hpp"
|
#include "game/gui/image_gallery.hpp"
|
||||||
#include "game/gui/label.hpp"
|
#include "game/gui/label.hpp"
|
||||||
@ -40,24 +39,24 @@ SOFTWARE.
|
|||||||
#include "game/world/player_manager.hpp"
|
#include "game/world/player_manager.hpp"
|
||||||
|
|
||||||
static const std::vector<float> cube_vertices = {
|
static const std::vector<float> cube_vertices = {
|
||||||
0.0f, 0.0f, 1.0f,
|
-0.05f, -0.05f, 1.05f,
|
||||||
1.0f, 0.0f, 1.0f,
|
1.05f, -0.05f, 1.05f,
|
||||||
1.0f, 1.0f, 1.0f,
|
1.05f, 1.05f, 1.05f,
|
||||||
0.0f, 1.0f, 1.0f,
|
-0.05f, 1.05f, 1.05f,
|
||||||
0.0f, 1.0f, 0.0f,
|
-0.05f, 1.05f, -0.05f,
|
||||||
1.0f, 1.0f, 0.0f,
|
1.05f, 1.05f, -0.05f,
|
||||||
1.0f, 0.0f, 0.0f,
|
1.05f, -0.05f, -0.05f,
|
||||||
0.0f, 0.0f, 0.0f,
|
-0.05f, -0.05f, -0.05f,
|
||||||
1.0f, 0.0f, 1.0f,
|
1.05f, -0.05f, 1.05f,
|
||||||
1.0f, 0.0f, 0.0f,
|
1.05f, -0.05f, -0.05f,
|
||||||
1.0f, 1.0f, 0.0f,
|
1.05f, 1.05f, -0.05f,
|
||||||
1.0f, 1.0f, 1.0f,
|
1.05f, 1.05f, 1.05f,
|
||||||
0.0f, 0.0f, 0.0f,
|
-0.05f, -0.05f, -0.05f,
|
||||||
0.0f, 0.0f, 1.0f,
|
-0.05f, -0.05f, 1.05f,
|
||||||
0.0f, 1.0f, 1.0f,
|
-0.05f, 1.05f, 1.05f,
|
||||||
0.0f, 1.0f, 0.0f,
|
-0.05f, 1.05f, -0.05f,
|
||||||
0.0f, 1.0f, 1.0f,
|
-0.05f, 1.05f, 1.05f,
|
||||||
1.0f, 1.0f, 1.0f
|
1.05f, 1.05f, 1.05f
|
||||||
};
|
};
|
||||||
static const std::vector<float> cube_uvs = {
|
static const std::vector<float> cube_uvs = {
|
||||||
0.0f, 0.0f,
|
0.0f, 0.0f,
|
||||||
@ -94,14 +93,15 @@ EditmodeHUD::EditmodeHUD(engine::Engine* engine, world::PlayerManager& player_ma
|
|||||||
engine::ResourceManager& resource_manager) :
|
engine::ResourceManager& resource_manager) :
|
||||||
HUD(engine),
|
HUD(engine),
|
||||||
m_selected_node(0),
|
m_selected_node(0),
|
||||||
m_ray_target(),
|
|
||||||
m_player_manager(player_manager),
|
m_player_manager(player_manager),
|
||||||
m_chunk_manager(chunk_manager),
|
m_chunk_manager(chunk_manager),
|
||||||
m_cube_mesh(engine->get_master_renderer()->create_mesh()),
|
m_cube_mesh(engine->get_master_renderer()->create_mesh()),
|
||||||
m_preview_shader(engine->get_master_renderer()->create_shader()),
|
m_preview_shader(engine->get_master_renderer()->create_shader()),
|
||||||
m_selected_node_texture(nullptr),
|
m_selected_node_texture(nullptr),
|
||||||
m_label_target(nullptr),
|
m_label_target(nullptr),
|
||||||
m_label_position(nullptr)
|
m_label_position(nullptr),
|
||||||
|
m_start(std::chrono::steady_clock::now()),
|
||||||
|
m_ray(chunk_manager)
|
||||||
{
|
{
|
||||||
m_cube_mesh->load_from_memory(cube_vertices, cube_indices, cube_uvs);
|
m_cube_mesh->load_from_memory(cube_vertices, cube_indices, cube_uvs);
|
||||||
m_preview_shader->load_from_file("node_preview");
|
m_preview_shader->load_from_file("node_preview");
|
||||||
@ -136,12 +136,15 @@ EditmodeHUD::~EditmodeHUD() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EditmodeHUD::render() {
|
void EditmodeHUD::render() {
|
||||||
|
if(!m_ray.is_hit())
|
||||||
|
return;
|
||||||
renderer::MeshRenderer* const mesh_renderer = m_engine->get_mesh_renderer();
|
renderer::MeshRenderer* const mesh_renderer = m_engine->get_mesh_renderer();
|
||||||
mesh_renderer->set_3d_rendering_mode(true);
|
mesh_renderer->set_3d_rendering_mode(true);
|
||||||
mesh_renderer->set_alpha_blending_mode(true);
|
mesh_renderer->set_alpha_blending_mode(true);
|
||||||
mesh_renderer->set_shader(m_preview_shader);
|
mesh_renderer->set_shader(m_preview_shader);
|
||||||
mesh_renderer->translate(math::Vector3f{std::floor(m_ray_target[0]), std::floor(m_ray_target[1]), std::floor(m_ray_target[2])});
|
mesh_renderer->translate(m_ray.get_hit_node().convert<float>());
|
||||||
mesh_renderer->render_textured(m_cube_mesh, m_selected_node_texture);
|
std::chrono::duration<float> interval = std::chrono::steady_clock::now()-m_start;
|
||||||
|
mesh_renderer->render(m_cube_mesh, math::RGBAColorf{0, 0, (std::sin(interval.count()*2)+1)/2.0f, 0.4f});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditmodeHUD::update(double delta) {
|
void EditmodeHUD::update(double delta) {
|
||||||
@ -151,18 +154,32 @@ void EditmodeHUD::update(double delta) {
|
|||||||
update_position_text();
|
update_position_text();
|
||||||
if(camera_controller->offset_changed() || local_player.is_moving() || m_chunk_manager.get_updated_chunks()>0)
|
if(camera_controller->offset_changed() || local_player.is_moving() || m_chunk_manager.get_updated_chunks()>0)
|
||||||
update_ray();
|
update_ray();
|
||||||
if(camera_controller->is_place_node_req())
|
if(m_ray.is_hit()) {
|
||||||
m_chunk_manager.try_place(m_ray_target.convert<int>(), m_selected_node);
|
if(camera_controller->is_place_node_req()) {
|
||||||
|
m_chunk_manager.try_place(m_ray.get_next_node(), m_selected_node);
|
||||||
|
m_chunk_manager.set_node(m_ray.get_next_node(), m_selected_node);
|
||||||
|
update_ray();
|
||||||
|
}
|
||||||
|
else if(camera_controller->is_dig_node_req()) {
|
||||||
|
m_chunk_manager.try_place(m_ray.get_hit_node(), 0);
|
||||||
|
m_chunk_manager.set_node(m_ray.get_hit_node(), 0);
|
||||||
|
update_ray();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditmodeHUD::event(const window::Event& ev) {}
|
void EditmodeHUD::event(const window::Event& ev) {}
|
||||||
|
|
||||||
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();
|
||||||
engine::Ray ray(m_chunk_manager, local_player.get_position(), local_player.get_view_direction());
|
m_ray.cast(local_player.get_position(), local_player.get_view_direction());
|
||||||
m_ray_target = ray.cast();
|
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
stream<<static_cast<int>(m_ray_target[0])<<" "<<static_cast<int>(m_ray_target[1])<<" "<<static_cast<int>(m_ray_target[2]);
|
if(m_ray.is_hit()) {
|
||||||
|
const math::Vector3i& ray_target = m_ray.get_hit_node();
|
||||||
|
stream<<ray_target[0]<<" "<<ray_target[1]<<" "<<ray_target[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
stream<<"none";
|
||||||
m_label_target->set_text(stream.str());
|
m_label_target->set_text(stream.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,10 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include "game/hud/hud.hpp"
|
#include "game/hud/hud.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include "common/math/vector.hpp"
|
#include "common/math/vector.hpp"
|
||||||
|
#include "game/engine/ray.hpp"
|
||||||
|
|
||||||
namespace polygun::engine {
|
namespace polygun::engine {
|
||||||
class ContentRegistry;
|
class ContentRegistry;
|
||||||
@ -61,7 +64,6 @@ namespace polygun::hud {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t m_selected_node;
|
uint16_t m_selected_node;
|
||||||
math::Vector3f m_ray_target;
|
|
||||||
world::PlayerManager& m_player_manager;
|
world::PlayerManager& m_player_manager;
|
||||||
world::ChunkManager& m_chunk_manager;
|
world::ChunkManager& m_chunk_manager;
|
||||||
renderer::Mesh* m_cube_mesh;
|
renderer::Mesh* m_cube_mesh;
|
||||||
@ -69,6 +71,8 @@ namespace polygun::hud {
|
|||||||
renderer::Texture* m_selected_node_texture;
|
renderer::Texture* m_selected_node_texture;
|
||||||
gui::Label* m_label_target;
|
gui::Label* m_label_target;
|
||||||
gui::Label* m_label_position;
|
gui::Label* m_label_position;
|
||||||
|
std::chrono::time_point<std::chrono::steady_clock> m_start;
|
||||||
|
engine::Ray m_ray;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update_ray();
|
void update_ray();
|
||||||
|
@ -88,16 +88,7 @@ void ChunkManager::on_packet(network::NetworkPacket& packet) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const math::Vector3i node_pos{x, y, z};
|
const math::Vector3i node_pos{x, y, z};
|
||||||
math::Vector3i chunk_pos = node_pos/math::Vector3i(world::Chunk::CHUNK_SIZE);
|
set_node(node_pos, node);
|
||||||
math::Vector3i local_node_pos = node_pos.abs()%math::Vector3i(world::Chunk::CHUNK_SIZE);
|
|
||||||
for(unsigned char i = 0; i<3; i++) {
|
|
||||||
if(node_pos[i]<0)
|
|
||||||
chunk_pos[i]--;
|
|
||||||
}
|
|
||||||
LoadedChunk* const chunk = get_loaded_chunk(chunk_pos);
|
|
||||||
chunk->m_chunk->add_node(node, local_node_pos);
|
|
||||||
chunk->m_updated = true;
|
|
||||||
m_updated_chunks++;
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -177,6 +168,19 @@ void ChunkManager::try_place(const math::Vector3i& node_pos, uint16_t node) {
|
|||||||
m_network_manager->send_packet(packet);
|
m_network_manager->send_packet(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChunkManager::set_node(const math::Vector3i& node_pos, uint16_t node) {
|
||||||
|
math::Vector3i chunk_pos = node_pos/math::Vector3i(world::Chunk::CHUNK_SIZE);
|
||||||
|
math::Vector3i local_node_pos = node_pos.abs()%math::Vector3i(world::Chunk::CHUNK_SIZE);
|
||||||
|
for(unsigned char i = 0; i<3; i++) {
|
||||||
|
if(node_pos[i]<0)
|
||||||
|
chunk_pos[i]--;
|
||||||
|
}
|
||||||
|
LoadedChunk* const chunk = get_loaded_chunk(chunk_pos);
|
||||||
|
chunk->m_chunk->add_node(node, local_node_pos);
|
||||||
|
chunk->m_updated = true;
|
||||||
|
m_updated_chunks++;
|
||||||
|
}
|
||||||
|
|
||||||
void ChunkManager::request_chunk(const math::Vector3i& pos) {
|
void ChunkManager::request_chunk(const math::Vector3i& pos) {
|
||||||
acquire();
|
acquire();
|
||||||
std::vector<LoadedChunk>::iterator it = std::find_if(m_loaded_chunks.begin(), m_loaded_chunks.end(), [pos](const LoadedChunk& chunk) {
|
std::vector<LoadedChunk>::iterator it = std::find_if(m_loaded_chunks.begin(), m_loaded_chunks.end(), [pos](const LoadedChunk& chunk) {
|
||||||
|
@ -68,6 +68,7 @@ namespace polygun::world {
|
|||||||
void render();
|
void render();
|
||||||
void try_place(const math::Vector3i& node_pos, uint16_t node);
|
void try_place(const math::Vector3i& node_pos, uint16_t node);
|
||||||
|
|
||||||
|
void set_node(const math::Vector3i& node_pos, uint16_t node);
|
||||||
void request_chunk(const math::Vector3i& pos);
|
void request_chunk(const math::Vector3i& pos);
|
||||||
world::Chunk& get_chunk(const math::Vector3i& pos);
|
world::Chunk& get_chunk(const math::Vector3i& pos);
|
||||||
uint16_t get_node(const math::Vector3i& node_pos);
|
uint16_t get_node(const math::Vector3i& node_pos);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user