Vehicle & destructible bullet hitboxes
This commit is contained in:
parent
8c52678e79
commit
45cf603c83
@ -21,6 +21,10 @@ static collision::Material GetMaterialByName(const std::string& name)
|
||||
return collision::PM_GLASS;
|
||||
else if (name == "flesh")
|
||||
return collision::PM_FLESH;
|
||||
else if (name == "car") // TODO: make new material for cars
|
||||
return collision::PM_METAL;
|
||||
else if (name == "carwindow")
|
||||
return collision::PM_NONE;
|
||||
else
|
||||
return collision::PM_STONE;
|
||||
}
|
||||
@ -35,7 +39,7 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
|
||||
std::unique_ptr<btConvexHullShape> temp_hull;
|
||||
std::unique_ptr<btCompoundShape> compound;
|
||||
|
||||
bool current_collision = true;
|
||||
collision::Material col_material = collision::PM_NONE;
|
||||
|
||||
LoadCMDFile(filename, [&](const std::string& command, std::istringstream& iss) {
|
||||
if (command == "v")
|
||||
@ -91,7 +95,7 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
|
||||
mb.AddTriangle(t);
|
||||
)
|
||||
|
||||
if (current_collision && model->cmesh_)
|
||||
if (model->cmesh_)
|
||||
{
|
||||
glm::vec3 p[3];
|
||||
for (size_t i = 0; i < 3; ++i)
|
||||
@ -225,19 +229,18 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
|
||||
{
|
||||
std::string pm_name;
|
||||
iss >> pm_name;
|
||||
if (pm_name == "none")
|
||||
|
||||
if (model->cmesh_)
|
||||
{
|
||||
current_collision = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_collision = true;
|
||||
if (model->cmesh_)
|
||||
{
|
||||
model->cmesh_->BeginMaterial(GetMaterialByName(pm_name));
|
||||
}
|
||||
model->cmesh_->BeginMaterial(GetMaterialByName(pm_name));
|
||||
}
|
||||
}
|
||||
else if (command == "cpm")
|
||||
{
|
||||
std::string pm_name;
|
||||
iss >> pm_name;
|
||||
col_material = GetMaterialByName(pm_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Unknown command in model file: " + command);
|
||||
@ -268,6 +271,13 @@ std::shared_ptr<const assets::Model> assets::Model::LoadFromFile(const std::stri
|
||||
model->cshape_ = std::move(compound);
|
||||
}
|
||||
|
||||
if (model->cshape_)
|
||||
{
|
||||
collision::SetShapeMaterial(*model->cshape_, col_material);
|
||||
if (col_material != collision::PM_NONE)
|
||||
model->cshape_is_bullet_target_ = true;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
@ -45,6 +45,7 @@ public:
|
||||
const glm::vec3& GetColOffset() const { return col_offset_; }
|
||||
const collision::TriangleMesh* GetColMesh() const { return cmesh_.get(); }
|
||||
btCollisionShape* GetColShape() const { return cshape_.get(); }
|
||||
bool IsColShapeBulletTarget() const { return cshape_is_bullet_target_; }
|
||||
|
||||
const std::shared_ptr<const Skeleton>& GetSkeleton() const { return skeleton_; }
|
||||
CLIENT_ONLY(const std::shared_ptr<const Mesh>& GetMesh() const { return mesh_; })
|
||||
@ -60,6 +61,7 @@ private:
|
||||
// std::vector<ModelCollisionShape> cshapes_;
|
||||
std::vector<std::unique_ptr<btCollisionShape>> subshapes_;
|
||||
std::unique_ptr<btCollisionShape> cshape_;
|
||||
bool cshape_is_bullet_target_ = false;
|
||||
|
||||
std::shared_ptr<const Skeleton> skeleton_;
|
||||
CLIENT_ONLY(std::shared_ptr<const Mesh> mesh_;);
|
||||
|
||||
@ -9,6 +9,7 @@ namespace collision
|
||||
|
||||
enum Material : uint8_t
|
||||
{
|
||||
PM_NONE,
|
||||
PM_STONE,
|
||||
PM_DIRT,
|
||||
PM_GRASS,
|
||||
|
||||
@ -11,6 +11,9 @@ void collision::TriangleMesh::BeginMaterial(Material material)
|
||||
|
||||
void collision::TriangleMesh::AddTriangle(const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2)
|
||||
{
|
||||
if (current_material_ == PM_NONE)
|
||||
return;
|
||||
|
||||
btVector3 bt_v0(v0.x, v0.y, v0.z);
|
||||
btVector3 bt_v1(v1.x, v1.y, v1.z);
|
||||
btVector3 bt_v2(v2.x, v2.y, v2.z);
|
||||
|
||||
@ -26,7 +26,7 @@ public:
|
||||
btBvhTriangleMeshShape* GetShape() const { return bt_shape_.get(); }
|
||||
|
||||
private:
|
||||
Material current_material_ = PM_STONE;
|
||||
Material current_material_ = PM_NONE;
|
||||
btTriangleMesh bt_mesh_;
|
||||
std::unique_ptr<btBvhTriangleMeshShape> bt_shape_;
|
||||
std::vector<Material> tri_materials_;
|
||||
|
||||
@ -76,11 +76,19 @@ game::MapObjectCollision::MapObjectCollision(collision::DynamicsWorld& world,
|
||||
model_->GetParamFloat("destr_th", destr_th_);
|
||||
}
|
||||
|
||||
col_group_ = collision::OG_DEFAULT;
|
||||
col_mask_ = collision::OG_ALL;
|
||||
|
||||
// prefer simple cshape which allow destruction
|
||||
if (cshape)
|
||||
{
|
||||
body_ = std::make_unique<btRigidBody>(
|
||||
btRigidBody::btRigidBodyConstructionInfo(mass, nullptr, cshape, local_inertia));
|
||||
|
||||
if (!model_->IsColShapeBulletTarget())
|
||||
{
|
||||
col_mask_ &= ~collision::OG_PROJECTILE;
|
||||
}
|
||||
}
|
||||
else if (cmesh)
|
||||
{
|
||||
@ -96,7 +104,7 @@ game::MapObjectCollision::MapObjectCollision(collision::DynamicsWorld& world,
|
||||
collision::SetObjectInfo(body_.get(), collision::OT_MAP_OBJECT, oflags, this);
|
||||
|
||||
// world_.GetBtWorld().addRigidBody(body_.get(), btBroadphaseProxy::StaticFilter, btBroadphaseProxy::AllFilter);
|
||||
world_.GetBtWorld().addRigidBody(body_.get());
|
||||
world_.GetBtWorld().addRigidBody(body_.get(), col_group_, col_mask_);
|
||||
}
|
||||
|
||||
void game::MapObjectCollision::Break()
|
||||
@ -122,7 +130,7 @@ void game::MapObjectCollision::Break()
|
||||
|
||||
collision::SetObjectInfo(body_.get(), collision::OT_UNDEFINED, 0, this);
|
||||
|
||||
world_.GetBtWorld().addRigidBody(body_.get());
|
||||
world_.GetBtWorld().addRigidBody(body_.get(), col_group_, col_mask_);
|
||||
}
|
||||
|
||||
void game::MapObjectCollision::GetModelTransform(Transform& trans) const
|
||||
|
||||
@ -31,6 +31,8 @@ public:
|
||||
net::ObjNum GetNum() const { return num_; }
|
||||
float GetDestroyThreshold() const { return destr_th_; }
|
||||
|
||||
int col_group_ = 0, col_mask_ = 0;
|
||||
|
||||
virtual ~MapObjectCollision() override;
|
||||
|
||||
private:
|
||||
|
||||
@ -38,6 +38,11 @@ void game::Vehicle::Update()
|
||||
{
|
||||
Super::Update();
|
||||
|
||||
if (physics_)
|
||||
{
|
||||
physics_->Update();
|
||||
}
|
||||
|
||||
root_.UpdateMatrix();
|
||||
|
||||
flags_ = 0;
|
||||
@ -99,7 +104,7 @@ void game::Vehicle::OnBulletHit(const game::BulletInfo& bullet, const btCollisio
|
||||
if (!physics_)
|
||||
return;
|
||||
|
||||
auto impulse = glm::normalize(bullet.end - bullet.start) * 10000.0f;
|
||||
auto impulse = glm::normalize(bullet.end - bullet.start) * 100.0f;
|
||||
physics_->GetBtBody().activate();
|
||||
physics_->GetBtBody().applyCentralImpulse(btVector3(impulse.x, impulse.y, impulse.z));
|
||||
}
|
||||
@ -728,6 +733,25 @@ game::VehiclePhysics::VehiclePhysics(collision::DynamicsWorld& world, Transform&
|
||||
bt_world.addRigidBody(body_.get(), collision::OG_DEFAULT, ~collision::OG_PROJECTILE);
|
||||
bt_world.addAction(vehicle_.get());
|
||||
|
||||
|
||||
// make bullet hitbox
|
||||
auto col_mesh = model.GetModel()->GetColMesh();
|
||||
if (col_mesh)
|
||||
{
|
||||
bullet_hitbox_ = std::make_unique<btCollisionObject>();
|
||||
bullet_hitbox_->setCollisionShape(col_mesh->GetShape());
|
||||
collision::SetObjectInfo(bullet_hitbox_.get(), collision::OT_ENTITY, 0, &obj_cb);
|
||||
|
||||
bt_world.addCollisionObject(bullet_hitbox_.get(), collision::OG_DEFAULT, collision::OG_PROJECTILE);
|
||||
|
||||
UpdateBulletHitboxTransform();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void game::VehiclePhysics::Update()
|
||||
{
|
||||
UpdateBulletHitboxTransform();
|
||||
}
|
||||
|
||||
game::VehiclePhysics::~VehiclePhysics()
|
||||
@ -735,4 +759,17 @@ game::VehiclePhysics::~VehiclePhysics()
|
||||
auto& bt_world = world_.GetBtWorld();
|
||||
bt_world.removeRigidBody(body_.get());
|
||||
bt_world.removeAction(vehicle_.get());
|
||||
|
||||
if (bullet_hitbox_)
|
||||
{
|
||||
bt_world.removeCollisionObject(bullet_hitbox_.get());
|
||||
}
|
||||
}
|
||||
|
||||
void game::VehiclePhysics::UpdateBulletHitboxTransform()
|
||||
{
|
||||
if (!bullet_hitbox_)
|
||||
return;
|
||||
|
||||
bullet_hitbox_->setWorldTransform(body_->getWorldTransform());
|
||||
}
|
||||
|
||||
@ -41,16 +41,22 @@ public:
|
||||
|
||||
DELETE_COPY_MOVE(VehiclePhysics)
|
||||
|
||||
void Update();
|
||||
|
||||
btRigidBody& GetBtBody() { return *body_; }
|
||||
collision::RaycastVehicle& GetBtVehicle() { return *vehicle_; }
|
||||
|
||||
~VehiclePhysics();
|
||||
|
||||
private:
|
||||
void UpdateBulletHitboxTransform();
|
||||
|
||||
private:
|
||||
collision::DynamicsWorld& world_;
|
||||
collision::MotionState motion_;
|
||||
std::unique_ptr<btRigidBody> body_;
|
||||
std::unique_ptr<collision::RaycastVehicle> vehicle_;
|
||||
std::unique_ptr<btCollisionObject> bullet_hitbox_;
|
||||
};
|
||||
|
||||
class Vehicle : public Entity
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user