Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/plugin/physics/src/component/ConvexHullMeshCollider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,23 @@

#pragma once

#include "component/Mesh.hpp"
#include <optional>

namespace Physics::Component {

/**
* @brief Convex hull mesh collider
*
* This component creates a convex hull collision shape from the entity's
* Object::Mesh component vertices. The convex hull is computed automatically
* This component creates a convex hull collision shape from mesh data.
* The mesh can either be embedded in this component or retrieved from the
* entity's Object::Mesh component. The convex hull is computed automatically
* by Jolt Physics from the mesh vertices.
*
* If this component is present on an entity with RigidBody, it uses the
* mesh geometry for collision instead of requiring an explicit collider.
*
* @note The entity MUST have an Object::Mesh component for this to work.
* @note If mesh is not embedded, the entity MUST have an Object::Mesh component.
* @note Convex hulls are more expensive than primitives (Box, Sphere, Capsule)
* but much cheaper than concave mesh colliders.
* @note Jolt automatically computes the convex hull from the provided points,
Expand All @@ -46,6 +50,9 @@ struct ConvexHullMeshCollider {
/// Smaller values = sharper corners, larger values = smoother but less accurate
float maxConvexRadius = 0.05f;

/// Optional embedded mesh data for collision (avoids needing entity Mesh component)
std::optional<Object::Component::Mesh> mesh;

/**
* @brief Default constructor
*/
Expand Down
13 changes: 10 additions & 3 deletions src/plugin/physics/src/component/MeshCollider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,23 @@

#pragma once

#include "component/Mesh.hpp"
#include <optional>

namespace Physics::Component {

/**
* @brief Triangle mesh collider (concave mesh support)
*
* This component creates a triangle mesh collision shape from the entity's
* Object::Mesh component vertices and indices. This supports concave meshes,
* This component creates a triangle mesh collision shape from mesh data.
* The mesh can either be embedded in this component or retrieved from the
* entity's Object::Mesh component. This supports concave meshes,
* making it ideal for static terrain, floors, and complex geometry.
*
* If this component is present on an entity with RigidBody, it uses the
* mesh geometry for collision instead of requiring an explicit collider.
*
* @note The entity MUST have an Object::Mesh component for this to work.
* @note If mesh is not embedded, the entity MUST have an Object::Mesh component.
* @note Triangle mesh colliders should ONLY be used for STATIC objects.
* For dynamic objects, use primitive colliders or convex hulls.
* @note The mesh scale from the Transform component is automatically applied.
Expand All @@ -46,6 +50,9 @@ struct MeshCollider {
/// Lower values = more edges marked as active = smoother sliding
float activeEdgeCosThresholdAngle = 0.996195f;

/// Optional embedded mesh data for collision (avoids needing entity Mesh component)
std::optional<Object::Component::Mesh> mesh;

/**
* @brief Default constructor
*/
Expand Down
36 changes: 30 additions & 6 deletions src/plugin/physics/src/system/RigidBodySystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ static JPH::RefConst<JPH::Shape> CreateMeshShapeFromMesh(const Object::Component
* @note If no collider is found, it will default to the MeshCollider with default settings, which can be pretty heavy.
* Make sure to always use the most appropriate colliders for RigidBodies.
*/
static JPH::RefConst<JPH::Shape> CreateShapeFromColliders(Engine::Core::Registry &registry, Engine::EntityId entity)
static JPH::RefConst<JPH::Shape> CreateShapeFromColliders(Engine::Core::Registry &registry, // NOSONAR
Engine::EntityId entity) // NOSONAR
{
if (auto *sphereCollider = registry.try_get<Component::SphereCollider>(entity))
{
Expand Down Expand Up @@ -187,10 +188,21 @@ static JPH::RefConst<JPH::Shape> CreateShapeFromColliders(Engine::Core::Registry

if (auto *convexHullCollider = registry.try_get<Component::ConvexHullMeshCollider>(entity))
{
auto *mesh = registry.try_get<Object::Component::Mesh>(entity);
const Object::Component::Mesh *mesh = nullptr;

if (convexHullCollider->mesh.has_value())
{
mesh = &convexHullCollider->mesh.value();
}
else
{
mesh = registry.try_get<Object::Component::Mesh>(entity);
}

if (!mesh)
{
Log::Warn("ConvexHullMeshCollider: trying to create shape without Object::Mesh component");
Log::Warn("ConvexHullMeshCollider: trying to create shape without mesh data (no embedded mesh or "
"Object::Mesh component)");
return nullptr;
}

Expand All @@ -203,10 +215,22 @@ static JPH::RefConst<JPH::Shape> CreateShapeFromColliders(Engine::Core::Registry
return CreateConvexHullFromMesh(*mesh, convexHullCollider, scale);
}

auto *mesh = registry.try_get<Object::Component::Mesh>(entity);
auto *meshCollider = registry.try_get<Component::MeshCollider>(entity);
const Object::Component::Mesh *mesh = nullptr;

if (meshCollider && meshCollider->mesh.has_value())
{
mesh = &meshCollider->mesh.value();
}
else
{
mesh = registry.try_get<Object::Component::Mesh>(entity);
}

if (!mesh)
{
Log::Warn("MeshCollider: trying to create shape without Object::Mesh component");
Log::Warn(
"MeshCollider: trying to create shape without mesh data (no embedded mesh or Object::Mesh component)");
return nullptr;
}

Expand All @@ -216,7 +240,7 @@ static JPH::RefConst<JPH::Shape> CreateShapeFromColliders(Engine::Core::Registry
scale = transform->GetScale();
}

return CreateMeshShapeFromMesh(*mesh, registry.try_get<Component::MeshCollider>(entity), scale);
return CreateMeshShapeFromMesh(*mesh, meshCollider, scale);
}

//=============================================================================
Expand Down
Loading