Node editing improvements
This commit is contained in:
parent
7fea96083d
commit
cf7b56167b
@ -4,8 +4,8 @@ in vec2 out_uv;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
uniform sampler2D uniform_texture_num;
|
||||
uniform vec4 uniform_color;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
protected:
|
||||
math::Vector2f m_offset;
|
||||
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) {
|
||||
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_dig_node_req = event.m_data.m_mouse_event.m_button==window::MouseButton::MOUSE_BUTTON_LEFT;
|
||||
break;
|
||||
case window::EventType::EVENT_TYPE_MOUSE_MOVE:
|
||||
m_offset[0] = event.m_data.m_mouse_event.m_relative_x;
|
||||
|
@ -32,17 +32,30 @@ SOFTWARE.
|
||||
|
||||
using namespace polygun::engine;
|
||||
|
||||
Ray::Ray(world::ChunkManager& chunk_manager, const math::Vector3f& source, const math::Vector3f& direction) :
|
||||
m_chunk_manager(chunk_manager),
|
||||
m_source(source),
|
||||
m_direction(direction)
|
||||
Ray::Ray(world::ChunkManager& chunk_manager) :
|
||||
m_chunk_manager(chunk_manager)
|
||||
{}
|
||||
|
||||
polygun::math::Vector3f Ray::cast() {
|
||||
math::Vector3f current_position = m_source;
|
||||
const math::Vector3f step = m_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) {
|
||||
void Ray::cast(const math::Vector3f& source, const math::Vector3f& direction) {
|
||||
math::Vector3f current_position = source;
|
||||
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_hit = source.distance(current_position)<8)) {
|
||||
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 {
|
||||
class Ray final {
|
||||
public:
|
||||
Ray(world::ChunkManager& chunk_manager, const math::Vector3f& source, const math::Vector3f& direction);
|
||||
Ray(world::ChunkManager& chunk_manager);
|
||||
~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:
|
||||
world::ChunkManager& m_chunk_manager;
|
||||
math::Vector3f m_source;
|
||||
math::Vector3f m_direction;
|
||||
bool m_hit;
|
||||
math::Vector3i m_hit_node;
|
||||
math::Vector3i m_next_node;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@ SOFTWARE.
|
||||
|
||||
#include "game/engine/engine.hpp"
|
||||
#include "game/engine/content_registry.hpp"
|
||||
#include "game/engine/ray.hpp"
|
||||
#include "game/engine/resource_manager.hpp"
|
||||
#include "game/gui/image_gallery.hpp"
|
||||
#include "game/gui/label.hpp"
|
||||
@ -40,24 +39,24 @@ SOFTWARE.
|
||||
#include "game/world/player_manager.hpp"
|
||||
|
||||
static const std::vector<float> cube_vertices = {
|
||||
0.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 1.0f,
|
||||
0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f,
|
||||
0.0f, 1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f
|
||||
-0.05f, -0.05f, 1.05f,
|
||||
1.05f, -0.05f, 1.05f,
|
||||
1.05f, 1.05f, 1.05f,
|
||||
-0.05f, 1.05f, 1.05f,
|
||||
-0.05f, 1.05f, -0.05f,
|
||||
1.05f, 1.05f, -0.05f,
|
||||
1.05f, -0.05f, -0.05f,
|
||||
-0.05f, -0.05f, -0.05f,
|
||||
1.05f, -0.05f, 1.05f,
|
||||
1.05f, -0.05f, -0.05f,
|
||||
1.05f, 1.05f, -0.05f,
|
||||
1.05f, 1.05f, 1.05f,
|
||||
-0.05f, -0.05f, -0.05f,
|
||||
-0.05f, -0.05f, 1.05f,
|
||||
-0.05f, 1.05f, 1.05f,
|
||||
-0.05f, 1.05f, -0.05f,
|
||||
-0.05f, 1.05f, 1.05f,
|
||||
1.05f, 1.05f, 1.05f
|
||||
};
|
||||
static const std::vector<float> cube_uvs = {
|
||||
0.0f, 0.0f,
|
||||
@ -94,14 +93,15 @@ EditmodeHUD::EditmodeHUD(engine::Engine* engine, world::PlayerManager& player_ma
|
||||
engine::ResourceManager& resource_manager) :
|
||||
HUD(engine),
|
||||
m_selected_node(0),
|
||||
m_ray_target(),
|
||||
m_player_manager(player_manager),
|
||||
m_chunk_manager(chunk_manager),
|
||||
m_cube_mesh(engine->get_master_renderer()->create_mesh()),
|
||||
m_preview_shader(engine->get_master_renderer()->create_shader()),
|
||||
m_selected_node_texture(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_preview_shader->load_from_file("node_preview");
|
||||
@ -136,12 +136,15 @@ EditmodeHUD::~EditmodeHUD() {
|
||||
}
|
||||
|
||||
void EditmodeHUD::render() {
|
||||
if(!m_ray.is_hit())
|
||||
return;
|
||||
renderer::MeshRenderer* const mesh_renderer = m_engine->get_mesh_renderer();
|
||||
mesh_renderer->set_3d_rendering_mode(true);
|
||||
mesh_renderer->set_alpha_blending_mode(true);
|
||||
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->render_textured(m_cube_mesh, m_selected_node_texture);
|
||||
mesh_renderer->translate(m_ray.get_hit_node().convert<float>());
|
||||
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) {
|
||||
@ -151,18 +154,32 @@ void EditmodeHUD::update(double delta) {
|
||||
update_position_text();
|
||||
if(camera_controller->offset_changed() || local_player.is_moving() || m_chunk_manager.get_updated_chunks()>0)
|
||||
update_ray();
|
||||
if(camera_controller->is_place_node_req())
|
||||
m_chunk_manager.try_place(m_ray_target.convert<int>(), m_selected_node);
|
||||
if(m_ray.is_hit()) {
|
||||
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::update_ray() {
|
||||
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_target = ray.cast();
|
||||
m_ray.cast(local_player.get_position(), local_player.get_view_direction());
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,10 @@ SOFTWARE.
|
||||
|
||||
#include "game/hud/hud.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "common/math/vector.hpp"
|
||||
#include "game/engine/ray.hpp"
|
||||
|
||||
namespace polygun::engine {
|
||||
class ContentRegistry;
|
||||
@ -61,7 +64,6 @@ namespace polygun::hud {
|
||||
|
||||
private:
|
||||
uint16_t m_selected_node;
|
||||
math::Vector3f m_ray_target;
|
||||
world::PlayerManager& m_player_manager;
|
||||
world::ChunkManager& m_chunk_manager;
|
||||
renderer::Mesh* m_cube_mesh;
|
||||
@ -69,6 +71,8 @@ namespace polygun::hud {
|
||||
renderer::Texture* m_selected_node_texture;
|
||||
gui::Label* m_label_target;
|
||||
gui::Label* m_label_position;
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_start;
|
||||
engine::Ray m_ray;
|
||||
|
||||
private:
|
||||
void update_ray();
|
||||
|
@ -88,16 +88,7 @@ void ChunkManager::on_packet(network::NetworkPacket& packet) {
|
||||
break;
|
||||
}
|
||||
const math::Vector3i node_pos{x, y, z};
|
||||
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++;
|
||||
set_node(node_pos, node);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@ -177,6 +168,19 @@ void ChunkManager::try_place(const math::Vector3i& node_pos, uint16_t node) {
|
||||
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) {
|
||||
acquire();
|
||||
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 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);
|
||||
world::Chunk& get_chunk(const math::Vector3i& pos);
|
||||
uint16_t get_node(const math::Vector3i& node_pos);
|
||||
|
Loading…
x
Reference in New Issue
Block a user