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 "assets/cache.hpp"
#include "collision/dynamicsworld.hpp"
#define GLM_ENABLE_EXPERIMENTAL
#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");
}
@ -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,6 +70,33 @@ 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<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,
@ -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
#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<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
{
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<assets::MapLoader> loader_;
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))
throw EntityInitError();
map_ = std::make_unique<MapInstanceView>(std::string(mapname));
map_ = std::make_unique<MapInstanceView>(*this, std::string(mapname));
// init destroyed objs
net::ObjCount objcount;