mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
Compare commits
3 Commits
9fc94c56b5
...
1af41db615
| Author | SHA1 | Date | |
|---|---|---|---|
| 1af41db615 | |||
| 1e17474122 | |||
| b24ce458dc |
@@ -26,9 +26,6 @@ class DevPanel {
|
||||
int gait = 0;
|
||||
float pos[3] = {0.0f, 0.0f, 0.0f};
|
||||
};
|
||||
struct TextEditing {
|
||||
bool perlin_seed = false;
|
||||
};
|
||||
|
||||
public:
|
||||
DevPanel(App& app);
|
||||
@@ -40,7 +37,6 @@ private:
|
||||
ConfigView m_config;
|
||||
ClientPlayer* m_player;
|
||||
PlayerProfile m_player_profile;
|
||||
TextEditing m_text_editing;
|
||||
bool m_need_save_config = false;
|
||||
bool m_gen_thread_running = true;
|
||||
int m_theme = 0;
|
||||
|
||||
@@ -32,7 +32,6 @@ public:
|
||||
void update();
|
||||
void hot_reload();
|
||||
|
||||
void rebuild_world();
|
||||
int rendering_distance() const;
|
||||
void rendering_distance(int rendering_distance);
|
||||
void start_gen_thread();
|
||||
@@ -131,7 +130,6 @@ private:
|
||||
std::atomic<bool> m_could_gen{true};
|
||||
std::atomic<bool> m_gen_running{false};
|
||||
std::atomic<bool> m_need_gen_chunk{false};
|
||||
std::atomic<bool> m_is_rebuilding{false};
|
||||
std::atomic<bool> m_init{false};
|
||||
std::atomic<bool> m_stopped{false};
|
||||
std::atomic<int> m_rendering_distance{24};
|
||||
|
||||
@@ -1,18 +1,108 @@
|
||||
#pragma once
|
||||
#include <algorithm>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
namespace Cubed {
|
||||
|
||||
namespace Math {
|
||||
|
||||
void extract_frustum_planes(const glm::mat4& mvp_matrix,
|
||||
std::vector<glm::vec4>& planes);
|
||||
inline void extract_frustum_planes(const glm::mat4& mvp_matrix,
|
||||
std::vector<glm::vec4>& planes) {
|
||||
if (planes.size() != 6) {
|
||||
planes.resize(6);
|
||||
}
|
||||
|
||||
float smootherstep(float edge0, float edge1, float x);
|
||||
bool is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents,
|
||||
const std::vector<glm::vec4>& planes);
|
||||
float deterministic_random(int x, int z, uint64_t seed);
|
||||
glm::vec3 slerp(const glm::vec3& from, const glm::vec3& to, float t);
|
||||
const float* m = glm::value_ptr(mvp_matrix);
|
||||
|
||||
// left plane
|
||||
planes[0] =
|
||||
glm::vec4(m[3] + m[0], m[7] + m[4], m[11] + m[8], m[15] + m[12]);
|
||||
// right plane
|
||||
planes[1] =
|
||||
glm::vec4(m[3] - m[0], m[7] - m[4], m[11] - m[8], m[15] - m[12]);
|
||||
// bottom plane
|
||||
planes[2] =
|
||||
glm::vec4(m[3] + m[1], m[7] + m[5], m[11] + m[9], m[15] + m[13]);
|
||||
// top plane
|
||||
planes[3] =
|
||||
glm::vec4(m[3] - m[1], m[7] - m[5], m[11] - m[9], m[15] - m[13]);
|
||||
// near plane
|
||||
planes[4] =
|
||||
glm::vec4(m[3] + m[2], m[7] + m[6], m[11] + m[10], m[15] + m[14]);
|
||||
// far plane
|
||||
planes[5] =
|
||||
glm::vec4(m[3] - m[2], m[7] - m[6], m[11] - m[10], m[15] - m[14]);
|
||||
|
||||
for (auto& p : planes) {
|
||||
p = glm::normalize(p);
|
||||
}
|
||||
}
|
||||
|
||||
inline float smootherstep(float edge0, float edge1, float x) {
|
||||
|
||||
x = std::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
|
||||
|
||||
return x * x * x * (x * (6.0f * x - 15.0f) + 10.0f);
|
||||
}
|
||||
|
||||
inline bool is_aabb_in_frustum(const glm::vec3& center,
|
||||
const glm::vec3& half_extents,
|
||||
const std::vector<glm::vec4>& planes) {
|
||||
for (const auto& plane : planes) {
|
||||
// distance
|
||||
float d = glm::dot(glm::vec3(plane), center) + plane.w;
|
||||
float r = half_extents.x * std::abs(plane.x) +
|
||||
half_extents.y * std::abs(plane.y) +
|
||||
half_extents.z * std::abs(plane.z);
|
||||
if (d + r < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
inline float deterministic_random(int x, int z, uint64_t seed) {
|
||||
uint64_t h = seed;
|
||||
h = h * 6364136223846793005ULL + (uint64_t)x;
|
||||
h = h * 6364136223846793005ULL + (uint64_t)z;
|
||||
return (float)(h >> 40) / (float)(1 << 24);
|
||||
}
|
||||
|
||||
inline glm::vec3 slerp(const glm::vec3& from, const glm::vec3& to, float t) {
|
||||
|
||||
float cos_theta = glm::clamp(glm::dot(from, to), -1.0f, 1.0f);
|
||||
|
||||
if (cos_theta > 0.9995f) {
|
||||
return glm::normalize(glm::mix(from, to, t));
|
||||
}
|
||||
|
||||
if (cos_theta < -0.9995f) {
|
||||
|
||||
glm::vec3 axis = (std::fabs(from.x) < 0.9f)
|
||||
? glm::vec3(1.0f, 0.0f, 0.0f)
|
||||
: glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
glm::vec3 ortho = glm::normalize(glm::cross(from, axis));
|
||||
|
||||
float angle = glm::pi<float>() * t;
|
||||
|
||||
glm::vec3 rotated =
|
||||
from * std::cos(angle) + glm::cross(ortho, from) * std::sin(angle);
|
||||
|
||||
return glm::normalize(rotated);
|
||||
}
|
||||
|
||||
float theta = std::acos(cos_theta);
|
||||
float sin_theta = std::sin(theta);
|
||||
|
||||
float a = std::sin((1.0f - t) * theta) / sin_theta;
|
||||
float b = std::sin(t * theta) / sin_theta;
|
||||
|
||||
return glm::normalize(a * from + b * to);
|
||||
}
|
||||
|
||||
inline float distance2(const glm::vec3& a, const glm::vec3& b) {
|
||||
glm::vec3 diff = a - b;
|
||||
return glm::dot(diff, diff);
|
||||
}
|
||||
|
||||
} // namespace Math
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ target_sources(${PROJECT_NAME}
|
||||
shader.cpp
|
||||
texture_manager.cpp
|
||||
tools/cubed_random.cpp
|
||||
tools/math_tools.cpp
|
||||
tools/shader_tools.cpp
|
||||
tools/font.cpp
|
||||
tools/perlin_noise.cpp
|
||||
|
||||
@@ -17,7 +17,6 @@ static constexpr const char* THEMES[] = {"Dark", "Light"};
|
||||
static constexpr const char* GAITS[] = {"Walk", "Run"};
|
||||
static constexpr const char* GAME_MODES[] = {"Creative", "Spectator"};
|
||||
static constexpr const char* CHUNK_LOAD_STYLE[] = {"Random", "Center"};
|
||||
static char perlin_noise_input_buffer[64];
|
||||
|
||||
constexpr float TEMP_MIN = 0.0f;
|
||||
constexpr float TEMP_MAX = 1.0f;
|
||||
@@ -47,16 +46,6 @@ constexpr float DELTA_ANGLE_MAX = 30.0f;
|
||||
constexpr int PATH_STEP_MIN = 1;
|
||||
constexpr int PATH_STEP_MAX = 1000;
|
||||
|
||||
static int filter_unsigned(ImGuiInputTextCallbackData* data) {
|
||||
if (data->EventFlag == ImGuiInputTextFlags_CallbackCharFilter) {
|
||||
char c = data->EventChar;
|
||||
if (c < '0' || c > '9') {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DevPanel::DevPanel(App& app) : m_app(app) {}
|
||||
|
||||
void DevPanel::init() {
|
||||
@@ -483,25 +472,8 @@ void DevPanel::show_world_tab_item() {
|
||||
}
|
||||
|
||||
void DevPanel::show_server_world_table_bar() {
|
||||
if (m_text_editing.perlin_seed) {
|
||||
if (ImGui::InputText("ChunkGenerator Seed", perlin_noise_input_buffer,
|
||||
sizeof(perlin_noise_input_buffer),
|
||||
ImGuiInputTextFlags_CallbackCharFilter |
|
||||
ImGuiInputTextFlags_EnterReturnsTrue,
|
||||
filter_unsigned)) {
|
||||
ChunkGenerator::seed(static_cast<unsigned int>(
|
||||
std::strtoul(perlin_noise_input_buffer, nullptr, 10)));
|
||||
m_text_editing.perlin_seed = false;
|
||||
m_player->set_player_pos({0.0f, 255.0f, 0.0f});
|
||||
m_app.server_world().rebuild_world();
|
||||
}
|
||||
}
|
||||
if (!m_text_editing.perlin_seed) {
|
||||
ImGui::Text("ChunkGenerator Seed: %u", ChunkGenerator::seed());
|
||||
if (ImGui::IsItemClicked()) {
|
||||
m_text_editing.perlin_seed = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Text("ChunkGenerator Seed: %u", ChunkGenerator::seed());
|
||||
|
||||
ImGui::Text("Pool Threads %d Max Support Threads %d Reserved Threads %d",
|
||||
m_app.server_world().gen_pool_threads(),
|
||||
@@ -525,12 +497,8 @@ void DevPanel::show_server_world_table_bar() {
|
||||
IM_ARRAYSIZE(CHUNK_LOAD_STYLE))) {
|
||||
m_app.server_world().set_chunk_load_style(m_chunk_style);
|
||||
}
|
||||
if (ImGui::Button("Rebuild World")) {
|
||||
m_app.server_world().rebuild_world();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Request Chunk Build")) {
|
||||
Logger::warn("This Request Chunk Build button is not finish");
|
||||
m_app.server_world().need_gen(m_player->get_uuid());
|
||||
}
|
||||
ImGui::SameLine();
|
||||
@@ -572,6 +540,10 @@ void DevPanel::show_client_world_table_bar() {
|
||||
m_app.client_world().rendering_distance(rendering_distance);
|
||||
// Config::get().set("world.rendering_distance", rendering_distance);
|
||||
}
|
||||
if (ImGui::Button("Rebuild World")) {
|
||||
m_app.client_world().rebuild_world();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Spawn Point")) {
|
||||
m_player->set_player_pos({0.0f, 255.0f, 0.0f});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Cubed/config.hpp"
|
||||
#include "Cubed/gameplay/game_time.hpp"
|
||||
#include "Cubed/gameplay/packet.hpp"
|
||||
#include "Cubed/tools/math_tools.hpp"
|
||||
|
||||
#include <numbers>
|
||||
|
||||
@@ -608,6 +609,11 @@ void ClientWorld::update(float delta_time) {
|
||||
for (auto& [uuid, player] : m_other_players) {
|
||||
player.render_pos =
|
||||
glm::mix(player.render_pos, player.target_pos, 0.15f);
|
||||
if (Math::distance2(player.render_pos, m_player.get_player_pos()) >
|
||||
m_rendering_distance * CHUNK_SIZE * m_rendering_distance *
|
||||
CHUNK_SIZE) {
|
||||
continue;
|
||||
}
|
||||
m_render_player_data.emplace_back(player.name, player.render_pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,40 +504,6 @@ void ServerWorld::hot_reload() {
|
||||
m_rendering_distance = dist <= MAX_DISTANCE ? dist : MAX_DISTANCE;
|
||||
}
|
||||
|
||||
void ServerWorld::rebuild_world() {
|
||||
if (m_is_rebuilding.exchange(true)) {
|
||||
return;
|
||||
}
|
||||
stop_gen_thread();
|
||||
stop_thread_pool();
|
||||
stop_server_thread();
|
||||
m_cave_carcer.reload(ChunkGenerator::seed());
|
||||
m_river_worm.reload(ChunkGenerator::seed());
|
||||
|
||||
m_chunks.clear();
|
||||
|
||||
{
|
||||
std::lock_guard lock(m_new_chunk_mutex);
|
||||
m_new_chunks.clear();
|
||||
}
|
||||
m_could_gen = true;
|
||||
ChunkGenerator::reload();
|
||||
start_thread_pool();
|
||||
start_gen_thread();
|
||||
start_server_thread();
|
||||
Arena arena;
|
||||
auto* rsp = Arena::Create<S2C_ClearAllChunks>(&arena);
|
||||
rsp->set_clear(true);
|
||||
{
|
||||
std::lock_guard lock(m_player_mutex);
|
||||
for (auto& [uuid, player] : m_players) {
|
||||
player.get_session()->send(make_packet(*rsp));
|
||||
}
|
||||
}
|
||||
|
||||
m_is_rebuilding = false;
|
||||
}
|
||||
|
||||
void ServerWorld::update() {
|
||||
// poll_finished_chunks();
|
||||
{
|
||||
@@ -585,7 +551,7 @@ void ServerWorld::sync_player_pos(const std::string& uuid, float x, float y,
|
||||
it->second.update_sync_gametick(m_game_ticks);
|
||||
name = it->second.get_name();
|
||||
}
|
||||
|
||||
ChunkPos pos = get_chunk_pos(x, z);
|
||||
// update other player pos;
|
||||
std::vector<std::shared_ptr<Session>> other;
|
||||
{
|
||||
@@ -594,11 +560,16 @@ void ServerWorld::sync_player_pos(const std::string& uuid, float x, float y,
|
||||
if (o_uuid == uuid) {
|
||||
continue;
|
||||
}
|
||||
other.emplace_back(player.get_session());
|
||||
if (player.has_player(pos)) {
|
||||
other.emplace_back(player.get_session());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& session : other) {
|
||||
if (!session) {
|
||||
continue;
|
||||
}
|
||||
Arena arena;
|
||||
auto* rsp = Arena::Create<PlayerInfoRsp>(&arena);
|
||||
rsp->set_uuid(uuid);
|
||||
@@ -694,7 +665,9 @@ void ServerWorld::handle_player_exit(const std::string& uuid) {
|
||||
}
|
||||
|
||||
for (auto& s : sessions) {
|
||||
s->send(make_packet(*rsp));
|
||||
if (s) {
|
||||
s->send(make_packet(*rsp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,15 +714,23 @@ void ServerWorld::handle_block_change(const BlockChangeReq& req) {
|
||||
pos->set_y(y);
|
||||
pos->set_z(z);
|
||||
rsp->set_block(req.block());
|
||||
std::vector<std::shared_ptr<Session>> sessions;
|
||||
auto chunk_pos = get_chunk_pos(x, z);
|
||||
{
|
||||
std::shared_lock lock(m_player_mutex);
|
||||
for (auto& [uuid, player] : m_players) {
|
||||
auto session = player.get_session();
|
||||
if (session) {
|
||||
session->send(make_packet(*rsp));
|
||||
if (player.has_player(chunk_pos)) {
|
||||
auto session = player.get_session();
|
||||
sessions.emplace_back(std::move(session));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& x : sessions) {
|
||||
if (x) {
|
||||
x->send(make_packet(*rsp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ServerWorld::rendering_distance() const {
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
#include "Cubed/tools/math_tools.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
namespace Math {
|
||||
|
||||
void extract_frustum_planes(const glm::mat4& mvp_matrix,
|
||||
std::vector<glm::vec4>& planes) {
|
||||
if (planes.size() != 6) {
|
||||
planes.resize(6);
|
||||
}
|
||||
|
||||
const float* m = glm::value_ptr(mvp_matrix);
|
||||
|
||||
// left plane
|
||||
planes[0] =
|
||||
glm::vec4(m[3] + m[0], m[7] + m[4], m[11] + m[8], m[15] + m[12]);
|
||||
// right plane
|
||||
planes[1] =
|
||||
glm::vec4(m[3] - m[0], m[7] - m[4], m[11] - m[8], m[15] - m[12]);
|
||||
// bottom plane
|
||||
planes[2] =
|
||||
glm::vec4(m[3] + m[1], m[7] + m[5], m[11] + m[9], m[15] + m[13]);
|
||||
// top plane
|
||||
planes[3] =
|
||||
glm::vec4(m[3] - m[1], m[7] - m[5], m[11] - m[9], m[15] - m[13]);
|
||||
// near plane
|
||||
planes[4] =
|
||||
glm::vec4(m[3] + m[2], m[7] + m[6], m[11] + m[10], m[15] + m[14]);
|
||||
// far plane
|
||||
planes[5] =
|
||||
glm::vec4(m[3] - m[2], m[7] - m[6], m[11] - m[10], m[15] - m[14]);
|
||||
|
||||
for (auto& p : planes) {
|
||||
p = glm::normalize(p);
|
||||
}
|
||||
}
|
||||
|
||||
float smootherstep(float edge0, float edge1, float x) {
|
||||
|
||||
x = std::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
|
||||
|
||||
return x * x * x * (x * (6.0f * x - 15.0f) + 10.0f);
|
||||
}
|
||||
|
||||
bool is_aabb_in_frustum(const glm::vec3& center, const glm::vec3& half_extents,
|
||||
const std::vector<glm::vec4>& planes) {
|
||||
for (const auto& plane : planes) {
|
||||
// distance
|
||||
float d = glm::dot(glm::vec3(plane), center) + plane.w;
|
||||
float r = half_extents.x * std::abs(plane.x) +
|
||||
half_extents.y * std::abs(plane.y) +
|
||||
half_extents.z * std::abs(plane.z);
|
||||
if (d + r < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
float deterministic_random(int x, int z, uint64_t seed) {
|
||||
uint64_t h = seed;
|
||||
h = h * 6364136223846793005ULL + (uint64_t)x;
|
||||
h = h * 6364136223846793005ULL + (uint64_t)z;
|
||||
return (float)(h >> 40) / (float)(1 << 24);
|
||||
}
|
||||
|
||||
glm::vec3 slerp(const glm::vec3& from, const glm::vec3& to, float t) {
|
||||
|
||||
float cos_theta = glm::clamp(glm::dot(from, to), -1.0f, 1.0f);
|
||||
|
||||
if (cos_theta > 0.9995f) {
|
||||
return glm::normalize(glm::mix(from, to, t));
|
||||
}
|
||||
|
||||
if (cos_theta < -0.9995f) {
|
||||
|
||||
glm::vec3 axis = (std::fabs(from.x) < 0.9f)
|
||||
? glm::vec3(1.0f, 0.0f, 0.0f)
|
||||
: glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
glm::vec3 ortho = glm::normalize(glm::cross(from, axis));
|
||||
|
||||
float angle = glm::pi<float>() * t;
|
||||
|
||||
glm::vec3 rotated =
|
||||
from * std::cos(angle) + glm::cross(ortho, from) * std::sin(angle);
|
||||
|
||||
return glm::normalize(rotated);
|
||||
}
|
||||
|
||||
float theta = std::acos(cos_theta);
|
||||
float sin_theta = std::sin(theta);
|
||||
|
||||
float a = std::sin((1.0f - t) * theta) / sin_theta;
|
||||
float b = std::sin(t * theta) / sin_theta;
|
||||
|
||||
return glm::normalize(a * from + b * to);
|
||||
}
|
||||
|
||||
} // namespace Math
|
||||
|
||||
} // namespace Cubed
|
||||
Reference in New Issue
Block a user