feat(physics): mesh collider#439
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 WalkthroughWalkthroughThis PR adds a MeshCollider component, replaces DefaultCollider usage with MeshCollider across the physics system, updates RigidBodySystem to generate ConvexHullShape colliders from mesh geometry when appropriate, and updates examples, vehicle builder, and collider docs to reflect the new mesh-first collider behavior. Changes
Sequence Diagram(s)sequenceDiagram
participant S as RigidBodySystem
participant E as Entity (Components)
participant Mesh as Object::Mesh
participant Colliders as Collider Components
participant J as Physics Engine (Jolt)
S->>E: Inspect components (RigidBody + colliders + mesh)
alt Sphere present
S->>J: Create SphereShape
else alt Capsule present
S->>J: Create CapsuleShape
else alt Box present
S->>J: Create BoxShape
else alt MeshCollider present
S->>Mesh: Extract vertices
S->>J: Create ConvexHullShape (use MeshCollider.maxConvexRadius)
else alt Mesh present (no collider)
S->>Mesh: Extract vertices
S->>J: Create ConvexHullShape (default config)
else
S->>S: Log warning (no collider/mesh)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/plugin/physics/src/component/BoxCollider.hpp (1)
37-42: Documentation example may have incorrect API signature.Same issue as in
MeshCollider.hpp- the example showsAddComponentwith two arguments, but actual usage in examples shows single-argument calls.Proposed fix
* `@code` * Physics::Component::BoxCollider collider; * collider.halfExtents = glm::vec3(0.5f, 1.0f, 0.5f); -* entity.AddComponent<Physics::BoxCollider>(core, collider); +* entity.AddComponent<Physics::Component::BoxCollider>(collider); * `@endcode`src/plugin/physics/src/component/CapsuleCollider.hpp (1)
55-61: Documentation example may have incorrect API signature.Consistent with the other collider headers, the example uses two-argument
AddComponentwhile actual usage appears to use single-argument calls.Proposed fix
* `@code` * Physics::Component::CapsuleCollider collider; * collider.halfHeight = 0.8f; // Cylinder part is 1.6m tall * collider.radius = 0.3f; // Total height = 1.6 + 0.6 = 2.2m -* entity.AddComponent<Physics::Component::CapsuleCollider>(core, collider); +* entity.AddComponent<Physics::Component::CapsuleCollider>(collider); * `@endcode`
🤖 Fix all issues with AI agents
In `@src/plugin/physics/src/builder/VehicleBuilder.hpp`:
- Line 212: The chassis was switched to a MeshCollider via
chassis.AddComponent<Component::MeshCollider>() which makes _chassisHalfExtents
and SetChassisHalfExtents() no-ops; update VehicleBuilder so
SetChassisHalfExtents() either (a) switches the chassis collider to a
BoxCollider and sets its extents (e.g., replace or add Component::BoxCollider to
the chassis when SetChassisHalfExtents is called), or (b) mark
SetChassisHalfExtents() deprecated/removed and add a new explicit API (e.g.,
SetChassisAsBox / UseBoxCollider) that adds Component::BoxCollider with the
provided extents while leaving MeshCollider as the default; ensure references to
chassis.AddComponent<Component::MeshCollider>(), _chassisHalfExtents, and
SetChassisHalfExtents() are updated accordingly and that behavior is
documented/covered by tests.
- Line 212: VehicleBuilder.hpp uses Component::MeshCollider in the call
chassis.AddComponent<Component::MeshCollider>() but does not include its header;
add the MeshCollider header include at the top of VehicleBuilder.hpp (e.g.,
include the MeshCollider declaration header such as "Component/MeshCollider.hpp"
or the project's corresponding header that defines Component::MeshCollider) so
the symbol is available for compilation.
In `@src/plugin/physics/src/component/MeshCollider.hpp`:
- Around line 44-53: The documentation example for MeshCollider uses the wrong
Entity::AddComponent signature by passing `core` explicitly; update the example
so calls to AddComponent match the actual API used elsewhere: call
entity.AddComponent<Physics::Component::MeshCollider>(collider) and
entity.AddComponent<Physics::Component::RigidBody>(rigidBody) (i.e., remove the
`core` argument) while keeping the same MeshCollider and RigidBody symbols and
descriptive comments.
In `@src/plugin/physics/src/system/RigidBodySystem.cpp`:
- Around line 32-68: CreateConvexHullFromMesh currently builds the hull from raw
mesh vertices without applying the entity Transform scale; update the function
signature (CreateConvexHullFromMesh) to accept a glm/Jolt-compatible scale
parameter (e.g., Vec3 scale), multiply each vertex by that scale before
converting with Utils::ToJoltVec3, and use the scaled joltPoints to construct
ConvexHullShapeSettings; also update the caller (CreateShapeFromColliders) to
pass the Transform's scale from the registry when invoking
CreateConvexHullFromMesh.
🧹 Nitpick comments (1)
src/plugin/physics/src/system/RigidBodySystem.cpp (1)
152-153: Add more context to the error log.The new error is a helpful guard, but it would be more actionable if it included the entity id (and possibly the mesh presence/vertex count) for faster debugging.
| /** | ||
| * @brief Create a ConvexHullShape from mesh vertices | ||
| * @param mesh The mesh component containing vertices | ||
| * @param meshCollider Mesh collider settings (convex radius) | ||
| * @return RefConst to the created shape, or nullptr on failure | ||
| */ | ||
| static JPH::RefConst<JPH::Shape> CreateConvexHullFromMesh(const Object::Component::Mesh &mesh, | ||
| const Component::MeshCollider &meshCollider) | ||
| { | ||
| const auto &vertices = mesh.GetVertices(); | ||
|
|
||
| if (vertices.empty()) | ||
| { | ||
| Log::Warn("MeshCollider: Mesh has no vertices, cannot create convex hull"); | ||
| return nullptr; | ||
| } | ||
|
|
||
| JPH::Array<JPH::Vec3> joltPoints; | ||
| joltPoints.reserve(vertices.size()); | ||
|
|
||
| for (const auto &vertex : vertices) | ||
| { | ||
| joltPoints.push_back(Utils::ToJoltVec3(vertex)); | ||
| } | ||
|
|
||
| float maxConvexRadius = meshCollider.maxConvexRadius; | ||
| JPH::ConvexHullShapeSettings settings(joltPoints, maxConvexRadius); | ||
|
|
||
| JPH::ShapeSettings::ShapeResult result = settings.Create(); | ||
| if (!result.IsValid()) | ||
| { | ||
| Log::Error(fmt::format("MeshCollider: Failed to create convex hull shape: {}", result.GetError().c_str())); | ||
| return nullptr; | ||
| } | ||
|
|
||
| return result.Get(); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, run the provided search to find Mesh component and GetVertices
rg -n "class Mesh|struct Mesh|GetVertices" -g '*.hpp' -g '*.cpp' | head -50Repository: EngineSquared/EngineSquared
Length of output: 4352
🏁 Script executed:
# Examine the Mesh component definition
cat -n src/plugin/object/src/component/Mesh.hpp | head -100Repository: EngineSquared/EngineSquared
Length of output: 3811
🏁 Script executed:
# Find where CreateConvexHullFromMesh is called in RigidBodySystem
rg -n "CreateConvexHullFromMesh" src/plugin/physics/src/system/RigidBodySystem.cpp -A 5 -B 5Repository: EngineSquared/EngineSquared
Length of output: 951
🏁 Script executed:
# Get more context around the call site to understand the function signature
sed -n '100,145p' src/plugin/physics/src/system/RigidBodySystem.cppRepository: EngineSquared/EngineSquared
Length of output: 1985
🏁 Script executed:
# Get the function signature that contains the CreateConvexHullFromMesh call
sed -n '70,145p' src/plugin/physics/src/system/RigidBodySystem.cppRepository: EngineSquared/EngineSquared
Length of output: 3232
🏁 Script executed:
# Check how SoftBodySystem uses scale with mesh vertices
sed -n '200,220p' src/plugin/physics/src/system/SoftBodySystem.cppRepository: EngineSquared/EngineSquared
Length of output: 1052
🏁 Script executed:
# Find the SoftBodySystem function signature that uses scale
sed -n '150,220p' src/plugin/physics/src/system/SoftBodySystem.cppRepository: EngineSquared/EngineSquared
Length of output: 2915
🏁 Script executed:
# Find where CreateJoltSharedSettings is called to see if scale is passed
rg -n "CreateJoltSharedSettings" src/plugin/physics/src/system/SoftBodySystem.cpp -B 2 -A 2Repository: EngineSquared/EngineSquared
Length of output: 659
🏁 Script executed:
# Find the function that calls CreateJoltSharedSettings at line 422
sed -n '380,430p' src/plugin/physics/src/system/SoftBodySystem.cppRepository: EngineSquared/EngineSquared
Length of output: 2190
🏁 Script executed:
# Check if RigidBodySystem applies scale elsewhere, or how rigid bodies use the created shapes
rg -n "GetOrCreateColliderShape\|CreateShapeFromColliders" src/plugin/physics/src/system/RigidBodySystem.cpp -A 10 | head -60Repository: EngineSquared/EngineSquared
Length of output: 53
🏁 Script executed:
# Search for where shapes are used with Transform in RigidBodySystem
rg -n "GetOrCreateColliderShape\|CreateShape" src/plugin/physics/src/system/RigidBodySystem.cppRepository: EngineSquared/EngineSquared
Length of output: 53
🏁 Script executed:
# Look for all usages of Transform in RigidBodySystem to see if scale is applied anywhere
rg -n "Transform\|scale" src/plugin/physics/src/system/RigidBodySystem.cpp | head -50Repository: EngineSquared/EngineSquared
Length of output: 53
🏁 Script executed:
# Get the full RigidBodySystem.cpp to understand the complete picture
wc -l src/plugin/physics/src/system/RigidBodySystem.cppRepository: EngineSquared/EngineSquared
Length of output: 124
🏁 Script executed:
# Read the entire RigidBodySystem.cpp
cat -n src/plugin/physics/src/system/RigidBodySystem.cppRepository: EngineSquared/EngineSquared
Length of output: 12795
Convex hull ignores Transform scale—mesh vertices need to be scaled during shape creation.
The mesh vertices are stored raw (not scale-baked) in the Mesh component. When CreateConvexHullFromMesh builds the convex hull, it does not apply the entity's Transform scale, resulting in incorrect physics geometry size. The SoftBodySystem already establishes the pattern of passing scale to mesh-based shape creation (see CreateJoltSharedSettings).
Pass the scale from the Transform to CreateConvexHullFromMesh and apply it to vertices:
🔧 Example adjustment
-static JPH::RefConst<JPH::Shape> CreateConvexHullFromMesh(const Object::Component::Mesh &mesh,
- const Component::MeshCollider &meshCollider)
+static JPH::RefConst<JPH::Shape> CreateConvexHullFromMesh(const Object::Component::Mesh &mesh,
+ const Component::MeshCollider &meshCollider,
+ const glm::vec3 &scale)
{
const auto &vertices = mesh.GetVertices();
@@
for (const auto &vertex : vertices)
{
- joltPoints.push_back(Utils::ToJoltVec3(vertex));
+ joltPoints.push_back(Utils::ToJoltVec3(vertex * scale));
}Then call it with the Transform's scale in CreateShapeFromColliders where the Transform is available via the registry.
🤖 Prompt for AI Agents
In `@src/plugin/physics/src/system/RigidBodySystem.cpp` around lines 32 - 68,
CreateConvexHullFromMesh currently builds the hull from raw mesh vertices
without applying the entity Transform scale; update the function signature
(CreateConvexHullFromMesh) to accept a glm/Jolt-compatible scale parameter
(e.g., Vec3 scale), multiply each vertex by that scale before converting with
Utils::ToJoltVec3, and use the scaled joltPoints to construct
ConvexHullShapeSettings; also update the caller (CreateShapeFromColliders) to
pass the Transform's scale from the registry when invoking
CreateConvexHullFromMesh.
|



Not related to any issues.
Add support form mesh colliders using Jolt's
ConvexHullShape.The "DefaultCollider" was useless and was remove. Instead, if a user doesn't add any collider, a mesh collider will be used by default.
Existing colliders (Box, Sphere) can still be used, they are a lot less expensive for simple shapes than full mesh colliders.
See the updated physics example (with graphics) for more detail
Summary by CodeRabbit
New Features
Documentation
Refactor
Tests
✏️ Tip: You can customize this high-level summary in your review settings.