diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index 4fd0458..083d58a 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -47,6 +47,14 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(ASSIMP) +FetchContent_Declare( + JSONCPP + GIT_REPOSITORY "https://github.com/open-source-parsers/jsoncpp.git" + GIT_TAG "1.9.6" + GIT_SHALLOW ON +) +FetchContent_MakeAvailable(JSONCPP) + file(GLOB_RECURSE Sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp" ) @@ -58,6 +66,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE glfw) target_link_libraries(${PROJECT_NAME} PRIVATE Microsoft.GSL::GSL) target_link_libraries(${PROJECT_NAME} PRIVATE spdlog) target_link_libraries(${PROJECT_NAME} PRIVATE assimp::assimp) +target_link_libraries(${PROJECT_NAME} PRIVATE jsoncpp_static) if(WIN32) target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32) @@ -103,4 +112,18 @@ add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD "$" "$" COMMENT "Copying spdlog library files and symlinks to output directory" +) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "$" + COMMENT "Copying jsoncpp DLL/so to output directory" +) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + "$" + "$" + COMMENT "Copying jsoncpp library files and symlinks to output directory" ) \ No newline at end of file diff --git a/Client/src/asteroid/tick.cpp b/Client/src/asteroid/tick.cpp index 377f16d..d3aac0d 100644 --- a/Client/src/asteroid/tick.cpp +++ b/Client/src/asteroid/tick.cpp @@ -53,10 +53,15 @@ void Tick(veng::Engine& engine, std::float_t delta_time) { if (glfwGetKey(engine.vulkan_graphics->window->GetHandle(), GLFW_KEY_W) == GLFW_PRESS) { player->linear_acceleration = glm::normalize(forward) * 10.f; + player_flame->linear_velocity = player->linear_velocity; + player_flame->position = player->position; + player_flame->angular_velocity = player->angular_velocity; + player_flame->rotation = player->rotation; player_flame->visible = true; if (!w_laststate) { player->needsUpdate = true; + player_flame->needsUpdate = true; player->updateRedundantCount = 0; w_laststate = true; } @@ -65,6 +70,7 @@ void Tick(veng::Engine& engine, std::float_t delta_time) { player_flame->visible = false; if (w_laststate) { player->needsUpdate = true; + player_flame->needsUpdate = true; player->updateRedundantCount = 0; w_laststate = false; } diff --git a/Server/CMakeLists.txt b/Server/CMakeLists.txt index 79e1135..60742a3 100644 --- a/Server/CMakeLists.txt +++ b/Server/CMakeLists.txt @@ -48,6 +48,14 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(ASSIMP) +FetchContent_Declare( + JSONCPP + GIT_REPOSITORY "https://github.com/open-source-parsers/jsoncpp.git" + GIT_TAG "1.9.6" + GIT_SHALLOW ON +) +FetchContent_MakeAvailable(JSONCPP) + file(GLOB_RECURSE Sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp" ) @@ -59,6 +67,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE glfw) target_link_libraries(${PROJECT_NAME} PRIVATE Microsoft.GSL::GSL) target_link_libraries(${PROJECT_NAME} PRIVATE spdlog) target_link_libraries(${PROJECT_NAME} PRIVATE assimp::assimp) +target_link_libraries(${PROJECT_NAME} PRIVATE jsoncpp_static) if(WIN32) target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32) @@ -89,4 +98,18 @@ add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD "$" "$" COMMENT "Copying spdlog library files and symlinks to output directory" +) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "$" + COMMENT "Copying jsoncpp DLL/so to output directory" +) + +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + "$" + "$" + COMMENT "Copying jsoncpp library files and symlinks to output directory" ) \ No newline at end of file diff --git a/Server/src/server.cpp b/Server/src/server.cpp index f2016db..c089d07 100644 --- a/Server/src/server.cpp +++ b/Server/src/server.cpp @@ -8,12 +8,12 @@ #include "socket/wsa_manager.h" #include "utils/log.h" #include "utils/snowflake.h" -#include "vulkan_engine/asset/object/model.h" #include "utils/utils.h" +#include "vulkan_engine/asset/object/model.h" #define LISTENIP "::" #define LISTENPORT 9010 -#define TICKRATE 30 +#define TICKRATE 60 constexpr double TICKDELAY = (1 / TICKRATE); std::uint8_t CLIENTID = 0; @@ -24,7 +24,8 @@ std::list> CLIENTS; std::mutex CLIENTS_MUTEX; void EchoClient(utils::ThreadPool* tp, Network::IOCP* iocp, - std::shared_ptr NewSock, Network::Address NewAddr) { + std::shared_ptr NewSock, + Network::Address NewAddr) { if (NewSock->sock == 0) return; std::future> result; Packet::Header header; @@ -32,7 +33,7 @@ void EchoClient(utils::ThreadPool* tp, Network::IOCP* iocp, result = iocp->recv(NewSock, 14); recv_data = utils::CvtListToVector(result.get()); - + header.Deserialize(recv_data); result = iocp->recv(NewSock, header.body_length); @@ -79,6 +80,16 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) { } CLIENTS_MUTEX.unlock(); + for (auto it = MODELS.begin(); it != MODELS.end();) { + auto& model = it->second; + + if (model.shouldBeDestroyed) { + it = MODELS.erase(it); + continue; + } + ++it; + } + for (auto it = MODELS.begin(); it != MODELS.end();) { auto& model = it->second; @@ -89,12 +100,7 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) { } if (model.lifespan <= 0.f) { - it = MODELS.erase(it); - continue; - } - - if (model.shouldBeDestroyed) { - it = MODELS.erase(it); + it->second.shouldBeDestroyed = true; continue; } @@ -111,7 +117,13 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) { std::vector send_data; auto model_serialized = model.second.Serialize(); Packet::Header header; - header.opcode = Packet::Opcode::UPDATEMODEL; + + if (model.second.shouldBeDestroyed) { + header.opcode = Packet::Opcode::DESPAWNMODEL; + } else { + header.opcode = Packet::Opcode::UPDATEMODEL; + } + header.timestamp = glfwGetTime(); header.body_length = model_serialized.size(); auto header_serialized = header.Serialize(); @@ -119,14 +131,16 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) { header_serialized.end()); send_data.insert(send_data.end(), model_serialized.begin(), model_serialized.end()); - if (!model.second.needsUpdate && !needs_all_update) { + if (!model.second.needsUpdate && !needs_all_update && + !model.second.shouldBeDestroyed) { continue; } model.second.needsUpdate = false; if (iocp->send(client, send_data) == -1) { client->sock = 0; } - spdlog::debug("server-side updated : [{}:{}]", model.second.name, model.second.ID.snowflake); + // spdlog::debug("server-side updated : [{}:{}]", model.second.name, + // model.second.ID.snowflake); } } CLIENTS_MUTEX.unlock(); diff --git a/impl/vulkan_engine/vulkan/engine.cpp b/impl/vulkan_engine/vulkan/engine.cpp index 4337617..c4172a1 100644 --- a/impl/vulkan_engine/vulkan/engine.cpp +++ b/impl/vulkan_engine/vulkan/engine.cpp @@ -146,7 +146,7 @@ void Engine::Update() { vulkan_graphics->RenderModel(it.second); } - physics_controller_.invokeOnColisionEvent(thread_pool_, models_); + Physics::invokeOnColisionEvent(thread_pool_, models_); vulkan_graphics->EndFrame(); } @@ -240,7 +240,7 @@ void Engine::ResponseToServerAndRefresh(std::shared_ptr sock) { for (auto& it : models_) { if (it.second->ID == model->ID) { Interpolation(header, it.second, model); - spdlog::debug("model updated: [{}:{}]", model->name, model->ID.snowflake); + // spdlog::debug("model updated: [{}:{}]", model->name, model->ID.snowflake); found = true; break; } @@ -250,8 +250,17 @@ void Engine::ResponseToServerAndRefresh(std::shared_ptr sock) { auto spawnedModel = SpawnLifedModel(model->asset_name, model->name, model->lifespan); std::lock_guard lock(spawnedModel->modding); - spawnedModel->ID = model->ID; + spawnedModel->position = model->position; + spawnedModel->linear_velocity = model->linear_velocity; + spawnedModel->linear_acceleration = model->linear_acceleration; + + spawnedModel->rotation = model->rotation; + spawnedModel->angular_velocity = model->angular_velocity; + spawnedModel->angular_acceleration = model->angular_acceleration; + + spawnedModel->scale = model->scale; + spawnedModel->transform = model->transform; spawnedModel->original_offset = model->original_offset; spawnedModel->radius = model->radius; @@ -260,11 +269,21 @@ void Engine::ResponseToServerAndRefresh(std::shared_ptr sock) { spawnedModel->visible = model->visible; spawnedModel->colision = model->colision; spawnedModel->networkReplicated = false; - - Interpolation(header, spawnedModel, model); spdlog::info("model spawned: {}", model->ID.snowflake); } } break; + case Packet::Opcode::DESPAWNMODEL: { + std::shared_ptr model = std::make_shared(); + model->Deserialize(recv_data); + + for (auto it = models_.begin(); it != models_.end();) { + if (it->second->ID == model->ID) { + models_.erase(it); + break; + } + ++it; + } + } break; default: spdlog::error("unknown data type"); } diff --git a/impl/vulkan_engine/vulkan/physics.cpp b/impl/vulkan_engine/vulkan/physics.cpp index a9bfb69..91b5863 100644 --- a/impl/vulkan_engine/vulkan/physics.cpp +++ b/impl/vulkan_engine/vulkan/physics.cpp @@ -12,18 +12,23 @@ void Physics::invokeOnColisionEvent( for (std::unordered_map>::iterator iter_A = models.begin(); iter_A != models.end(); iter_A++) { - auto model_A = iter_A->second; - if (!model_A->colision) continue; for (auto iter_B = std::next(iter_A); iter_B != models.end(); iter_B++) { + auto model_A = iter_A->second; + std::lock_guard Alock(model_A->modding); auto model_B = iter_B->second; - if (!model_B->colision) continue; + std::lock_guard Block(model_B->modding); + if (!model_A->colision || !model_B->colision) continue; std::float_t distance = glm::distance(model_A->position, model_B->position); std::float_t modelA_radius = model_A->radius * model_A->scale.x; std::float_t modelB_radius = model_B->radius * model_B->scale.x; if (distance <= modelA_radius + modelB_radius) { + model_A = iter_A->second; + model_B = iter_B->second; if (model_A->OnColision) thread_pool->enqueueJob(model_A->OnColision, model_A, model_B); + model_A = iter_A->second; + model_B = iter_B->second; if (model_B->OnColision) thread_pool->enqueueJob(model_B->OnColision, model_A, model_B); } diff --git a/include/utils/thread_pool.h b/include/utils/thread_pool.h index c92462e..0766490 100644 --- a/include/utils/thread_pool.h +++ b/include/utils/thread_pool.h @@ -51,8 +51,8 @@ class ThreadPool { } std::lock_guard lock(jobQueueMutex); - auto boundFunc = [this, __job, ... __args = __args]() mutable { - __job(this, __args...); + auto boundFunc = [this, __job, ... __args = std::move(__args)]() mutable { + __job(this, std::move(__args)...); }; auto task = std::packaged_task(std::move(boundFunc)); jobs_.push(std::move(task)); diff --git a/include/vulkan_engine/asset/object/model.h b/include/vulkan_engine/asset/object/model.h index 149a254..680bda2 100644 --- a/include/vulkan_engine/asset/object/model.h +++ b/include/vulkan_engine/asset/object/model.h @@ -166,7 +166,7 @@ struct Model { double lastUpdatedTime = 0.f; // 서버 기준 업데이트된 시간임 - std::uint8_t updateRedundantCount; + std::uint8_t updateRedundantCount = 0; std::mutex modding; diff --git a/include/vulkan_engine/vulkan/engine.h b/include/vulkan_engine/vulkan/engine.h index bd2d275..040ebb8 100644 --- a/include/vulkan_engine/vulkan/engine.h +++ b/include/vulkan_engine/vulkan/engine.h @@ -44,7 +44,6 @@ class Engine { private: Loader asset_loader_; - Physics physics_controller_; utils::ThreadPool* thread_pool_; Network::IOCP* iocp_; diff --git a/include/vulkan_engine/vulkan/physics.h b/include/vulkan_engine/vulkan/physics.h index c68d8c5..8614446 100644 --- a/include/vulkan_engine/vulkan/physics.h +++ b/include/vulkan_engine/vulkan/physics.h @@ -7,7 +7,7 @@ namespace veng { class Physics { public: - void invokeOnColisionEvent( + static void invokeOnColisionEvent( gsl::not_null thread_pool, std::unordered_map>& models);