Skip to content

Commit

Permalink
[physicsbody] bug fixes and transform accuracy improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
PanosK92 committed Jan 15, 2025
1 parent 8c25f2d commit a03153e
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 72 deletions.
23 changes: 2 additions & 21 deletions runtime/Game/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ namespace spartan

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

Expand Down Expand Up @@ -570,7 +569,6 @@ namespace spartan
{
// add physics so we can walk on it
PhysicsBody* physics_body = m_default_terrain->AddComponent<PhysicsBody>().get();
physics_body->SetMass(0.0f);
physics_body->SetShapeType(PhysicsShape::Terrain);

// water
Expand Down Expand Up @@ -634,7 +632,6 @@ namespace spartan
// make the bark collidable
shared_ptr<PhysicsBody> physics_body = bark->AddComponent<PhysicsBody>();
physics_body->SetShapeType(PhysicsShape::Mesh);
physics_body->SetMass(0.0f);
}

if (Entity* branches = entity->GetDescendantByName("Branches"))
Expand Down Expand Up @@ -744,7 +741,6 @@ namespace spartan
if (entity->IsActive() && entity->GetComponent<Renderable>() != nullptr)
{
PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(0.0f);
physics_body->SetShapeType(PhysicsShape::Mesh);
}
}
Expand Down Expand Up @@ -818,18 +814,8 @@ namespace spartan
entity->SetPosition(Vector3(0.0f, 14.0f, -355.5300f));
entity->SetScale(Vector3(0.1f, 0.1f, 0.1f));

// enable physics for all meshes
vector<Entity*> entities;
entity->GetDescendants(&entities);
for (Entity* entity : entities)
{
if (entity->GetComponent<Renderable>() != nullptr)
{
PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(0.0f);
physics_body->SetShapeType(PhysicsShape::Mesh);
}
}
PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetShapeType(PhysicsShape::Mesh);
}
}

Expand Down Expand Up @@ -860,7 +846,6 @@ namespace spartan
if (entity->IsActive() && entity->GetComponent<Renderable>() != nullptr)
{
PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(0.0f); // static
physics_body->SetShapeType(PhysicsShape::Mesh);
}
}
Expand Down Expand Up @@ -899,7 +884,6 @@ namespace spartan
if (entity->IsActive() && entity->GetComponent<Renderable>() != nullptr)
{
PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(0.0f);
physics_body->SetShapeType(PhysicsShape::Mesh);
}
}
Expand Down Expand Up @@ -928,7 +912,6 @@ namespace spartan
if (entity->GetComponent<Renderable>() != nullptr)
{
PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(0.0f);
physics_body->SetShapeType(PhysicsShape::Mesh);
}
}
Expand Down Expand Up @@ -956,7 +939,6 @@ namespace spartan
if (entity->GetComponent<Renderable>() != nullptr)
{
PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(0.0f);
physics_body->SetShapeType(PhysicsShape::Mesh);
}
}
Expand Down Expand Up @@ -1080,7 +1062,6 @@ namespace spartan
if (entity->GetComponent<Renderable>() != nullptr)
{
PhysicsBody* physics_body = entity->AddComponent<PhysicsBody>().get();
physics_body->SetMass(0.0f); // static
physics_body->SetShapeType(PhysicsShape::Mesh);
}
}
Expand Down
89 changes: 39 additions & 50 deletions runtime/World/Components/PhysicsBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,18 @@ namespace spartan
#define rigid_body static_cast<btRigidBody*>(m_rigid_body)
#define vehicle static_cast<btRaycastVehicle*>(m_vehicle)

btTransform compute_transform(const Vector3& position, const Quaternion& rotation, const Vector3& scale)
btTransform compute_transform(const Vector3& position, const Quaternion& rotation)
{
btTransform transform;
transform.setIdentity();

// to bullet
btQuaternion bt_rotation = quaternion_to_bt(rotation);
btVector3 bt_position = vector_to_bt(position);

btMatrix3x3& basis = transform.getBasis();
basis.setValue(scale.x, 0, 0,
0, scale.y, 0,
0, 0, scale.z);

// Create a transform from the rotation quaternion
btTransform rotation_transform(bt_rotation);
transform = rotation_transform * transform;

// Set the position

// to transform
btTransform transform;
transform.setIdentity();
transform.setRotation(bt_rotation);
transform.setOrigin(bt_position);

return transform;
}

Expand Down Expand Up @@ -879,64 +871,65 @@ namespace spartan

case PhysicsShape::Mesh:
{
function<void(Entity*, btCompoundShape*)> recursive_renderable_to_shape = [&](Entity* entity, btCompoundShape* compoundShape)
function<void(Entity*, btCompoundShape*, bool)> recursive_renderable_to_shape = [&](Entity* entity, btCompoundShape* shape_compount, const bool is_root_entity)
{
// get renderable
shared_ptr<Renderable> renderable = entity->GetComponent<Renderable>();
if (renderable)
{
// get geometry
vector<uint32_t> indices;
vector<RHI_Vertex_PosTexNorTan> vertices;
renderable->GetGeometry(&indices, &vertices);

if (vertices.empty())
{
SP_LOG_WARNING("PhysicsShape::Mesh requires the renderable component to contain vertices");
return;
}
// get geometry and save it as well
// geometry is saved because btTriangleIndexVertexArray only points it
PhysicsBodyMeshData& mesh_data = m_mesh_data.emplace_back();
renderable->GetGeometry(&mesh_data.indices, &mesh_data.vertices);

// the root/calling entity's position and rotation is control by the motion state, no need to apply it here
Vector3 position = is_root_entity ? Vector3::Zero : entity->GetPosition();
Quaternion rotation = is_root_entity ? Quaternion::Identity : entity->GetRotation();

// determine how much detail is needed for this shape
const bool is_enterable = can_player_fit(entity, vertices, size);
const bool convex_hull = !is_enterable;
const bool is_enterable = can_player_fit(entity, mesh_data.vertices, size);
const bool is_dynamic = m_mass > 0.0f;
const bool convex_hull = is_dynamic || !is_enterable;

if (convex_hull)
{
// create convex hull shape
btConvexHullShape* shape_convex = new btConvexHullShape(
reinterpret_cast<btScalar*>(&vertices[0]),
static_cast<uint32_t>(vertices.size()),
reinterpret_cast<btScalar*>(&mesh_data.vertices[0]),
static_cast<uint32_t>(mesh_data.vertices.size()),
static_cast<uint32_t>(sizeof(RHI_Vertex_PosTexNorTan))
);

shape_convex->optimizeConvexHull();
shape_convex->setLocalScaling(vector_to_bt(size));

// add to compound
if (renderable->HasInstancing())
{
for (uint32_t instance_index = 0; instance_index < renderable->GetInstanceCount(); instance_index++)
{
Matrix world_transform = renderable->GetInstanceTransform(instance_index);
compoundShape->addChildShape(compute_transform(world_transform.GetTranslation(), world_transform.GetRotation(), world_transform.GetScale()), shape_convex);
Matrix transform_instance = renderable->GetInstanceTransform(instance_index) * entity->GetMatrix();
shape_compount->addChildShape(compute_transform(transform_instance.GetTranslation(), transform_instance.GetRotation()), shape_convex);
}
}
else
{
compoundShape->addChildShape(compute_transform(Vector3::Zero, Quaternion::Identity, size), shape_convex);
shape_compount->addChildShape(compute_transform(position, rotation), shape_convex);
}
}
else
{
// simplify the geometry if not convex hull
geometry_processing::simplify(indices, vertices, static_cast<size_t>((indices.size() / 3) * 0.05f));
geometry_processing::simplify(mesh_data.indices, mesh_data.vertices, static_cast<size_t>((mesh_data.indices.size() / 3) * 0.05f));

// create triangle mesh shape
btTriangleIndexVertexArray* index_vertex_array = new btTriangleIndexVertexArray(
static_cast<int>(indices.size() / 3),
reinterpret_cast<int*>(&indices[0]),
static_cast<int>(mesh_data.indices.size() / 3),
reinterpret_cast<int*>(&mesh_data.indices[0]),
sizeof(uint32_t) * 3,
static_cast<int>(vertices.size()),
reinterpret_cast<float*>(&vertices[0].pos[0]),
sizeof(vertices[0])
static_cast<int>(mesh_data.vertices.size()),
reinterpret_cast<float*>(&mesh_data.vertices[0].pos[0]),
sizeof(mesh_data.vertices[0])
);

btBvhTriangleMeshShape* shape_triangle_mesh = new btBvhTriangleMeshShape(
Expand All @@ -945,28 +938,24 @@ namespace spartan
);

shape_triangle_mesh->setLocalScaling(vector_to_bt(size));

// set properties for kinematic static collision

m_is_kinematic = true;
m_mass = 0.0f;

compoundShape->addChildShape(compute_transform(Vector3::Zero, Quaternion::Identity, size), shape_triangle_mesh);

shape_compount->addChildShape(compute_transform(Vector3::Zero, Quaternion::Identity), shape_triangle_mesh);
}
}

// recursively process all children
vector<Entity*> children = entity->GetChildren();
for (Entity* child : children)
{
recursive_renderable_to_shape(child, compoundShape);
recursive_renderable_to_shape(child, shape_compount, false);
}
};

// create the compound shape
// recursively create a compound shape that contains the entity's hierarchy
btCompoundShape* shape_compound = new btCompoundShape();

// start the recursive process for this entity
recursive_renderable_to_shape(GetEntity(), shape_compound);
recursive_renderable_to_shape(GetEntity(), shape_compound, true);

m_shape = shape_compound;

Expand Down
9 changes: 8 additions & 1 deletion runtime/World/Components/PhysicsBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ namespace spartan
Max
};

struct PhysicsBodyMeshData
{
std::vector<uint32_t> indices;
std::vector<RHI_Vertex_PosTexNorTan> vertices;
};

class PhysicsBody : public Component
{
public:
Expand Down Expand Up @@ -166,7 +172,7 @@ namespace spartan
void RemoveBodyFromWorld();
void UpdateShape();

float m_mass = 1.0f;
float m_mass = 0.0f;
float m_friction = 1.0f;
float m_friction_rolling = 0.002f;
float m_restitution = 0.2f;
Expand All @@ -184,6 +190,7 @@ namespace spartan
void* m_shape = nullptr;
void* m_rigid_body = nullptr;
std::shared_ptr<Car> m_car = nullptr;
std::vector<PhysicsBodyMeshData> m_mesh_data;
std::vector<Constraint*> m_constraints;
};
}

0 comments on commit a03153e

Please sign in to comment.