Skip to content

Commit

Permalink
[physicsbody] setting the mass to PhysicsBody::mass_auto will now com…
Browse files Browse the repository at this point in the history
…pute a mass (kg) based on the volume of the shape, the material density is asssumed to be 80 since it provides "expected" values
  • Loading branch information
PanosK92 committed Jan 15, 2025
1 parent d79f96e commit ba83c72
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 13 deletions.
8 changes: 4 additions & 4 deletions runtime/Game/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ namespace spartan

// add physics components
shared_ptr<PhysicsBody> physics_body = entity->AddComponent<PhysicsBody>();
physics_body->SetMass(15.0f);
physics_body->SetMass(PhysicsBody::mass_auto);
physics_body->SetShapeType(PhysicsShape::Box);
}

Expand All @@ -428,7 +428,7 @@ namespace spartan
entity->SetScale(Vector3(1.7f, 1.7f, 1.7f));

PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(8.0f);
physics_body->SetMass(PhysicsBody::mass_auto);
physics_body->SetShapeType(PhysicsShape::Mesh, true);
}

Expand All @@ -441,7 +441,7 @@ namespace spartan
entity->SetScale(Vector3(0.3f, 0.3f, 0.3f));

PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(8.0f);
physics_body->SetMass(PhysicsBody::mass_auto);
physics_body->SetShapeType(PhysicsShape::Mesh);
}

Expand All @@ -456,7 +456,7 @@ namespace spartan
if (auto mesh_entity = entity->GetDescendantByName("Object_2"))
{
PhysicsBody* physics_body = mesh_entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(8.0f);
physics_body->SetMass(PhysicsBody::mass_auto);
physics_body->SetShapeType(PhysicsShape::Mesh);
}
}
Expand Down
40 changes: 31 additions & 9 deletions runtime/World/Components/PhysicsBody.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
Copyright(c) 2016-2025 Panos Karabelas
Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down Expand Up @@ -805,36 +805,45 @@ namespace spartan
}

Vector3 size = m_size * GetEntity()->GetScale();
float volume = 1.0f;

// construct new shape
switch (m_shape_type)
{

case PhysicsShape::Box:
m_shape = new btBoxShape(vector_to_bt(size * 0.5f));
volume = size.x * size.y * size.z; // volume of a box = width * height * depth
break;

case PhysicsShape::Sphere:
m_shape = new btSphereShape(size.x * 0.5f);
break;

case PhysicsShape::StaticPlane:
m_shape = new btStaticPlaneShape(btVector3(0.0f, 1.0f, 0.0f), 0.0f);
volume = (4.0f / 3.0f) * 3.14f * pow(size.x * 0.5f, 3); // volume of a sphere = (4/3)πr³
break;

case PhysicsShape::Cylinder:
m_shape = new btCylinderShape(vector_to_bt(size * 0.5f));
volume = 3.14f * pow(size.x * 0.5f, 2) * size.y; // volume of a cylinder = πr²h
break;

case PhysicsShape::Capsule:
{
float radius = helper::Max(size.x, size.z) * 0.5f;
float height = size.y;
m_shape = new btCapsuleShape(radius, height);
float radius = helper::Max(size.x, size.z) * 0.5f;
float height = size.y - 2.0f * radius; // exclude spherical caps from the cylindrical height
float sphere_volume = (4.0f / 3.0f) * 3.14f * pow(radius, 3); // volume of spherical caps
float cylinder_volume = 3.14f * pow(radius, 2) * height; // volume of cylindrical body
volume = sphere_volume + cylinder_volume;
m_shape = new btCapsuleShape(radius, size.y);
break;
}

case PhysicsShape::Cone:
m_shape = new btConeShape(size.x * 0.5f, size.y);
volume = (1.0f / 3.0f) * 3.14f * pow(size.x * 0.5f, 2) * size.y; // volume of a cone = (1/3)πr²h
break;

case PhysicsShape::StaticPlane:
m_shape = new btStaticPlaneShape(btVector3(0.0f, 1.0f, 0.0f), 0.0f);
break;

case PhysicsShape::Terrain:
Expand Down Expand Up @@ -879,6 +888,11 @@ namespace spartan
shared_ptr<Renderable> renderable = entity->GetComponent<Renderable>();
if (renderable)
{
if (is_root_entity)
{
volume = renderable->GetBoundingBox(BoundingBoxType::Transformed).Volume();
}

// get geometry and save it as well
// geometry is saved because btTriangleIndexVertexArray only points it
PhysicsBodyMeshData& mesh_data = m_mesh_data.emplace_back();
Expand Down Expand Up @@ -963,11 +977,19 @@ namespace spartan
recursive_renderable_to_shape(GetEntity(), shape_compound, true, m_replicate_hierarchy);

m_shape = shape_compound;

break;
}
}

if (volume > 0.0f && m_mass == mass_auto)
{
// objects can be hollow, have non-uniform density and be made of multiple materials
// we approximate this by using a small density which provides "expected" kg values
const float density = 80.0f;
m_mass = density * volume;
}

static_cast<btCollisionShape*>(m_shape)->setUserPointer(this);
AddBodyToWorld();
}
Expand Down
2 changes: 2 additions & 0 deletions runtime/World/Components/PhysicsBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ namespace spartan
void* GetBtRigidBody() const { return m_rigid_body; }
std::shared_ptr<Car> GetCar() { return m_car; }

constexpr static inline float mass_auto = FLT_MAX;

private:
void AddBodyToWorld();
void RemoveBodyFromWorld();
Expand Down

0 comments on commit ba83c72

Please sign in to comment.