Add convex hull option for meshes

This commit is contained in:
tovjemam 2026-01-14 18:04:24 +01:00
parent 8ae2183d59
commit 1e94a118eb
3 changed files with 44 additions and 22 deletions

View File

@ -3,12 +3,15 @@
#include "cmdfile.hpp" #include "cmdfile.hpp"
#include "cache.hpp" #include "cache.hpp"
#include <BulletCollision/CollisionShapes/btShapeHull.h>
std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::string& filename) std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::string& filename)
{ {
auto model = std::make_shared<Model>(); auto model = std::make_shared<Model>();
std::vector<glm::vec3> vert_pos; // rember for collision trimesh std::vector<glm::vec3> vert_pos; // rember for collision trimesh
CLIENT_ONLY(MeshBuilder mb(gfx::MF_NONE);) CLIENT_ONLY(MeshBuilder mb(gfx::MF_NONE);)
std::unique_ptr<btConvexHullShape> temp_hull;
LoadCMDFile(filename, [&](const std::string& command, std::istringstream& iss) { LoadCMDFile(filename, [&](const std::string& command, std::istringstream& iss) {
if (command == "v") if (command == "v")
@ -29,6 +32,9 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
if (model->cmesh_) if (model->cmesh_)
vert_pos.emplace_back(pos); vert_pos.emplace_back(pos);
if (temp_hull)
temp_hull->addPoint(btVector3(pos.x, pos.y, pos.z), false);
} }
else if (command == "f") else if (command == "f")
{ {
@ -92,6 +98,10 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
{ {
model->cmesh_ = std::make_unique<collision::TriangleMesh>(); model->cmesh_ = std::make_unique<collision::TriangleMesh>();
} }
else if (command == "makeconvexhull")
{
temp_hull = std::make_unique<btConvexHullShape>();
}
else else
{ {
throw std::runtime_error("Unknown command in model file: " + command); throw std::runtime_error("Unknown command in model file: " + command);
@ -105,8 +115,21 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
model->mesh_ = mb.GetMesh(); model->mesh_ = mb.GetMesh();
) )
// tri mesh
if (model->cmesh_) if (model->cmesh_)
model->cmesh_->Build(); model->cmesh_->Build();
// convex hull
if (temp_hull)
{
temp_hull->recalcLocalAabb();
// Optional but recommended
auto shape_hull = std::make_unique<btShapeHull>(temp_hull.get());
shape_hull->buildHull(temp_hull->getMargin());
model->cshape_ = std::make_unique<btConvexHullShape>((btScalar*)shape_hull->getVertexPointer(), shape_hull->numVertices(), sizeof(btVector3));
}
return model; return model;
} }

View File

@ -14,24 +14,25 @@
namespace assets namespace assets
{ {
enum ModelCollisionShapeType // enum ModelCollisionShapeType
{ // {
MCS_NONE, // MCS_NONE,
MCS_BOX, // MCS_BOX,
MCS_SPHERE, // MCS_SPHERE,
}; // };
// struct ModelCollisionShape
// {
// ModelCollisionShapeType type = MCS_NONE;
// glm::vec3 origin = glm::vec3(0.0f);
// union
// {
// float radius;
// glm::vec3 half_extents;
// };
// };
struct ModelCollisionShape
{
ModelCollisionShapeType type = MCS_NONE;
glm::vec3 origin = glm::vec3(0.0f);
union
{
float radius;
glm::vec3 half_extents;
};
};
class Model class Model
{ {
@ -40,13 +41,14 @@ public:
static std::shared_ptr<const Model> LoadFromFile(const std::string& filename); static std::shared_ptr<const Model> LoadFromFile(const std::string& filename);
const collision::TriangleMesh* GetColMesh() const { return cmesh_.get(); } const collision::TriangleMesh* GetColMesh() const { return cmesh_.get(); }
const std::vector<ModelCollisionShape>& GetColShapes() const { return cshapes_; } btCollisionShape* GetColShape() const { return cshape_.get(); }
CLIENT_ONLY(const std::shared_ptr<const Mesh>& GetMesh() const { return mesh_; }) CLIENT_ONLY(const std::shared_ptr<const Mesh>& GetMesh() const { return mesh_; })
private: private:
std::unique_ptr<collision::TriangleMesh> cmesh_; std::unique_ptr<collision::TriangleMesh> cmesh_;
std::vector<ModelCollisionShape> cshapes_; // std::vector<ModelCollisionShape> cshapes_;
std::unique_ptr<btCollisionShape> cshape_;
CLIENT_ONLY(std::shared_ptr<const Mesh> mesh_;) CLIENT_ONLY(std::shared_ptr<const Mesh> mesh_;)

View File

@ -58,8 +58,5 @@ void collision::DynamicsWorld::AddModelInstance(const assets::Model& model, cons
static_objs_.emplace_back(std::move(obj)); static_objs_.emplace_back(std::move(obj));
} }
for (const auto& shapes = model.GetColShapes(); const auto& shape : shapes) // TODO: add shape
{
// TODO: add basic shapes
}
} }