Bring back clientside collisions for camera

This commit is contained in:
zbyv 2026-03-24 21:34:17 +01:00
parent 9bf90cee69
commit 29c8b575d9
3 changed files with 112 additions and 7 deletions

View File

@ -1,10 +1,10 @@
#include "mapinstanceview.hpp" #include "mapinstanceview.hpp"
#include "assets/cache.hpp" #include "collision/dynamicsworld.hpp"
#define GLM_ENABLE_EXPERIMENTAL #define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/norm.hpp> #include <glm/gtx/norm.hpp>
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<assets::MapLoader>("data/" + map_name + ".map"); loader_ = std::make_unique<assets::MapLoader>("data/" + map_name + ".map");
} }
@ -19,8 +19,9 @@ void game::view::MapInstanceView::LoadNext()
// just loaded // just loaded
map_ = loader_->GetMap(); map_ = loader_->GetMap();
objs_visible_.resize(map_->GetStaticObjects().size(), true);
loader_.reset(); loader_.reset();
InitObjsAndCollisions();
} }
int game::view::MapInstanceView::GetLoadingPercent() const int game::view::MapInstanceView::GetLoadingPercent() const
@ -69,6 +70,33 @@ void game::view::MapInstanceView::EnableObj(net::ObjNum num, bool enable)
objs_visible_.resize(i + 1, true); objs_visible_.resize(i + 1, true);
objs_visible_[i] = enable; 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<MapObjectCollisionView>(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<MapObjectCollisionView>(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, void game::view::MapInstanceView::DrawChunk(const game::view::DrawArgs& args, const assets::Mesh& basemesh,
@ -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<const assets::Model> 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>(
btRigidBody::btRigidBodyConstructionInfo(0.0f, nullptr, cshape, local_inertia));
}
else if (cmesh)
{
body_ = std::make_unique<btRigidBody>(
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
}

View File

@ -1,16 +1,36 @@
#pragma once #pragma once
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "assets/map.hpp" #include "assets/map.hpp"
#include "collision/dynamicsworld.hpp"
#include "draw_args.hpp" #include "draw_args.hpp"
#include "net/defs.hpp" #include "net/defs.hpp"
#include "utils/defs.hpp"
namespace game::view namespace game::view
{ {
class MapObjectCollisionView
{
public:
MapObjectCollisionView(collision::DynamicsWorld& world, std::shared_ptr<const assets::Model> model, const Transform& trans);
DELETE_COPY_MOVE(MapObjectCollisionView)
void SetEnabled(bool enabled);
~MapObjectCollisionView();
private:
collision::DynamicsWorld& world_;
std::shared_ptr<const assets::Model> model_;
std::unique_ptr<btRigidBody> body_;
bool enabled_ = false;
};
class MapInstanceView class MapInstanceView
{ {
public: public:
MapInstanceView(const std::string& map_name); MapInstanceView(collision::DynamicsWorld& world, const std::string& map_name);
void LoadNext(); void LoadNext();
bool IsLoaded() const { return loader_.get() == nullptr; } bool IsLoaded() const { return loader_.get() == nullptr; }
@ -21,13 +41,19 @@ public:
void EnableObj(net::ObjNum num, bool enable); void EnableObj(net::ObjNum num, bool enable);
private: private:
void InitObjsAndCollisions();
void DrawChunk(const game::view::DrawArgs& args, const assets::Mesh& basemesh, const assets::Chunk& chunk) const; void DrawChunk(const game::view::DrawArgs& args, const assets::Mesh& basemesh, const assets::Chunk& chunk) const;
private: private:
collision::DynamicsWorld& world_;
std::unique_ptr<assets::MapLoader> loader_; std::unique_ptr<assets::MapLoader> loader_;
std::shared_ptr<const assets::Map> map_; std::shared_ptr<const assets::Map> map_;
std::vector<bool> objs_visible_;
std::unique_ptr<MapObjectCollisionView> basemodel_col_;
std::vector<bool> objs_visible_;
std::vector<std::unique_ptr<MapObjectCollisionView>> obj_cols_;
}; };

View File

@ -15,7 +15,7 @@ game::view::WorldView::WorldView(ClientSession& session, net::InMessage& msg) :
if (!msg.Read(mapname)) if (!msg.Read(mapname))
throw EntityInitError(); throw EntityInitError();
map_ = std::make_unique<MapInstanceView>(std::string(mapname)); map_ = std::make_unique<MapInstanceView>(*this, std::string(mapname));
// init destroyed objs // init destroyed objs
net::ObjCount objcount; net::ObjCount objcount;