From 29c8b575d9c5cfc98d35b3cb42522924696c2d5d Mon Sep 17 00:00:00 2001 From: zbyv Date: Tue, 24 Mar 2026 21:34:17 +0100 Subject: [PATCH] Bring back clientside collisions for camera --- src/gameview/mapinstanceview.cpp | 87 ++++++++++++++++++++++++++++++-- src/gameview/mapinstanceview.hpp | 30 ++++++++++- src/gameview/worldview.cpp | 2 +- 3 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/gameview/mapinstanceview.cpp b/src/gameview/mapinstanceview.cpp index f91deaa..c96d9dd 100644 --- a/src/gameview/mapinstanceview.cpp +++ b/src/gameview/mapinstanceview.cpp @@ -1,10 +1,10 @@ #include "mapinstanceview.hpp" -#include "assets/cache.hpp" +#include "collision/dynamicsworld.hpp" #define GLM_ENABLE_EXPERIMENTAL #include -game::view::MapInstanceView::MapInstanceView(const std::string& map_name) +game::view::MapInstanceView::MapInstanceView(collision::DynamicsWorld& world, const std::string& map_name) : world_(world) { loader_ = std::make_unique("data/" + map_name + ".map"); } @@ -19,8 +19,9 @@ void game::view::MapInstanceView::LoadNext() // just loaded map_ = loader_->GetMap(); - objs_visible_.resize(map_->GetStaticObjects().size(), true); loader_.reset(); + + InitObjsAndCollisions(); } int game::view::MapInstanceView::GetLoadingPercent() const @@ -69,10 +70,37 @@ void game::view::MapInstanceView::EnableObj(net::ObjNum num, bool enable) objs_visible_.resize(i + 1, true); objs_visible_[i] = enable; + + if (i < obj_cols_.size()) + { + obj_cols_[i]->SetEnabled(enable); + } +} + +void game::view::MapInstanceView::InitObjsAndCollisions() +{ + // add basemodel col + const auto& basemodel = map_->GetBaseModel(); + if (basemodel) + { + Transform identity; + basemodel_col_ = std::make_unique(world_, basemodel, identity); + basemodel_col_->SetEnabled(true); + } + + auto& objs = map_->GetStaticObjects(); + objs_visible_.resize(objs.size(), true); + obj_cols_.resize(objs.size()); + + for (size_t i = 0; i < objs.size(); ++i) + { + obj_cols_[i] = std::make_unique(world_, objs[i].model, objs[i].node.local); + obj_cols_[i]->SetEnabled(objs_visible_[i]); + } } void game::view::MapInstanceView::DrawChunk(const game::view::DrawArgs& args, const assets::Mesh& basemesh, - const assets::Chunk& chunk) const + const assets::Chunk& chunk) const { for (const auto& surface_range : chunk.surfaces) { @@ -117,3 +145,54 @@ void game::view::MapInstanceView::DrawChunk(const game::view::DrawArgs& args, co } } } + +game::view::MapObjectCollisionView::MapObjectCollisionView(collision::DynamicsWorld& world, + std::shared_ptr model, + const Transform& trans) : + world_(world), model_(std::move(model)) +{ + auto cshape = model_->GetColShape(); + auto cmesh = model_->GetColMesh(); + + btVector3 local_inertia(0, 0, 0); + + if (cshape) + { + body_ = std::make_unique( + btRigidBody::btRigidBodyConstructionInfo(0.0f, nullptr, cshape, local_inertia)); + } + else if (cmesh) + { + body_ = std::make_unique( + btRigidBody::btRigidBodyConstructionInfo(0.0f, nullptr, cmesh->GetShape(), local_inertia)); + } + + auto offset_trans = trans; + offset_trans.position += trans.rotation * model_->GetColOffset(); + + body_->setWorldTransform(offset_trans.ToBtTransform()); +} + +void game::view::MapObjectCollisionView::SetEnabled(bool enabled) +{ + if (enabled == enabled_) + return; + + auto& bt_world = world_.GetBtWorld(); + + if (enabled) + { + bt_world.addRigidBody(body_.get()); + } + else + { + bt_world.removeRigidBody(body_.get()); + } + + enabled_ = enabled; +} + +game::view::MapObjectCollisionView::~MapObjectCollisionView() +{ + SetEnabled(false); // delete from world if there +} diff --git a/src/gameview/mapinstanceview.hpp b/src/gameview/mapinstanceview.hpp index 9f33017..1c736b3 100644 --- a/src/gameview/mapinstanceview.hpp +++ b/src/gameview/mapinstanceview.hpp @@ -1,16 +1,36 @@ #pragma once +#include "BulletDynamics/Dynamics/btRigidBody.h" #include "assets/map.hpp" +#include "collision/dynamicsworld.hpp" #include "draw_args.hpp" #include "net/defs.hpp" +#include "utils/defs.hpp" namespace game::view { +class MapObjectCollisionView +{ +public: + MapObjectCollisionView(collision::DynamicsWorld& world, std::shared_ptr model, const Transform& trans); + DELETE_COPY_MOVE(MapObjectCollisionView) + + void SetEnabled(bool enabled); + + ~MapObjectCollisionView(); + +private: + collision::DynamicsWorld& world_; + std::shared_ptr model_; + std::unique_ptr body_; + bool enabled_ = false; +}; + class MapInstanceView { public: - MapInstanceView(const std::string& map_name); + MapInstanceView(collision::DynamicsWorld& world, const std::string& map_name); void LoadNext(); bool IsLoaded() const { return loader_.get() == nullptr; } @@ -21,13 +41,19 @@ public: void EnableObj(net::ObjNum num, bool enable); private: + void InitObjsAndCollisions(); + void DrawChunk(const game::view::DrawArgs& args, const assets::Mesh& basemesh, const assets::Chunk& chunk) const; private: + collision::DynamicsWorld& world_; std::unique_ptr loader_; std::shared_ptr map_; - std::vector objs_visible_; + std::unique_ptr basemodel_col_; + + std::vector objs_visible_; + std::vector> obj_cols_; }; diff --git a/src/gameview/worldview.cpp b/src/gameview/worldview.cpp index cbafdca..64988b3 100644 --- a/src/gameview/worldview.cpp +++ b/src/gameview/worldview.cpp @@ -15,7 +15,7 @@ game::view::WorldView::WorldView(ClientSession& session, net::InMessage& msg) : if (!msg.Read(mapname)) throw EntityInitError(); - map_ = std::make_unique(std::string(mapname)); + map_ = std::make_unique(*this, std::string(mapname)); // init destroyed objs net::ObjCount objcount;