Engine version: UE 5.8 (latest launcher build)
RMC version: Pro (Latest commit from Github)
So I must confess, I've been sat on this issue for nearly 2 years now and I've just not had the time to debug it and make a reasonable report so I was parked on UE5.4 and a version of RMC Pro from mid 2024 (commit hash: c44a4f164c9f849031134403dd9baa08db682df1) what I was able to deduce seince having some time to debug, was the specific issue/s I've been running into started HERE.
After the collision cooking was reworked, RMC seemingly stopped respecting FRealtimeMeshCollisionConvex::Center the resulting cooked collision body is always placed at 0,0,0 of the component it's added to.
For context, my project is a custom physics based vehicle game, players can attach arbitrary parts to their airships, engines, etc, when they do so, we we harvest out the collision bodies from the "part" over to the simple geometry of the airships "hull" (there's a specific reason we do this, it sucks, but it's mostly related to Unreal's character movement component being kinematically driven), the Center property was our way to pin that body to where it should be once copied over.
Here's a code extract from how we used to do this body copying (scoped down to just the ConvexHulls) from the 2024 commit hash I referenced above.
void UBSShipHullComponent::GetRMCCollisionBodies(
const ABSShipPart* ShipPart, TArray<FRealtimeMeshCollisionSphere>& CollisionSpheres,
TArray<FRealtimeMeshCollisionBox>& CollisionBoxes, TArray<FRealtimeMeshCollisionCapsule>& CollisionCapsules,
TArray<FRealtimeMeshCollisionTaperedCapsule>& CollisionTaperedCapsules, TArray<FRealtimeMeshCollisionConvex>& CollisionConvexes, const bool bEmpty) const
{
if (!ensureAlways(IsValid(ShipPart->GetMesh()))) return;
UBodySetup* BodySetup = ShipPart->GetPartBodySetup();
if (!ensureAlways(IsValid(BodySetup))) return;
const FTransform ShipPartComponentTransform = ShipPart->GetMesh()->GetComponentTransform();
const FTransform ShipHullComponentTransform = GetComponentTransform();
if (bEmpty)
{
CollisionSpheres.Empty();
CollisionBoxes.Empty();
CollisionCapsules.Empty();
CollisionTaperedCapsules.Empty();
CollisionConvexes.Empty();
}
for (const auto& Convex : BodySetup->AggGeom.ConvexElems)
{
auto& BodyConvex = CollisionConvexes.AddDefaulted_GetRef();
BodyConvex.Vertices = Convex.VertexData;
BodyConvex.BoundingBox = Convex.ElemBox;
FTransform ConvexTransform = Convex.GetTransform();
BodyConvex.Center = ShipHullComponentTransform.InverseTransformPosition(ShipPartComponentTransform.TransformPosition(ConvexTransform.GetLocation()));
BodyConvex.Rotation = ShipHullComponentTransform.InverseTransformRotation(ShipPartComponentTransform.TransformRotation(ConvexTransform.GetRotation())).Rotator();
// NOTE: We don't use the existing value of contribute to mass since we don't want the addition of this body to affect the CoM.
// BodyConvex.bContributesToMass = Convex.GetContributeToMass();
BodyConvex.bContributesToMass = false;
}
}
Since the second commit I've referenced, it seems we now have to explicitly transform the vertices of the body to be where it should end up ourselves rather than relying on the Center property as we used to.
void UBSShipHullComponent::GetRMCCollisionBodies(
const ABSShipPart* ShipPart, TArray<FRealtimeMeshCollisionSphere>& CollisionSpheres,
TArray<FRealtimeMeshCollisionBox>& CollisionBoxes, TArray<FRealtimeMeshCollisionCapsule>& CollisionCapsules,
TArray<FRealtimeMeshCollisionTaperedCapsule>& CollisionTaperedCapsules, TArray<FRealtimeMeshCollisionConvex>& CollisionConvexes, const bool bEmpty) const
{
if (!ensureAlways(IsValid(ShipPart->GetMesh()))) return;
UBodySetup* BodySetup = ShipPart->GetPartBodySetup();
if (!ensureAlways(IsValid(BodySetup))) return;
const FTransform ShipPartComponentTransform = ShipPart->GetMesh()->GetComponentTransform();
const FTransform ShipHullComponentTransform = GetComponentTransform();
if (bEmpty)
{
CollisionSpheres.Empty();
CollisionBoxes.Empty();
CollisionCapsules.Empty();
CollisionTaperedCapsules.Empty();
CollisionConvexes.Empty();
}
for (const auto& Convex : BodySetup->AggGeom.ConvexElems)
{
auto& BodyConvex = CollisionConvexes.AddDefaulted_GetRef();
FTransform ConvexTransform = Convex.GetTransform();
const FVector Center = ShipHullComponentTransform.InverseTransformPosition(ShipPartComponentTransform.TransformPosition(ConvexTransform.GetLocation()));
const FRotator Rotation = ShipHullComponentTransform.InverseTransformRotation(ShipPartComponentTransform.TransformRotation(ConvexTransform.GetRotation())).Rotator();
// FRealtimeMeshCollisionConvex::Center is no longer being respected, so now we have to apply the correct transform to the vertices here.
TArray<FVector> VertexData;
VertexData.SetNumUninitialized(Convex.VertexData.Num());
for (int i = 0; i < Convex.VertexData.Num(); i++)
{
VertexData[i] = FTransform(Rotation, Center).TransformPosition(Convex.VertexData[i]);
}
BodyConvex.SetVertices(VertexData);
BodyConvex.Center = Center;
BodyConvex.Rotation = Rotation;
// NOTE: We don't use the existing value of contribute to mass since we don't want the addition of this body to affect the CoM.
// BodyConvex.bContributesToMass = Convex.GetContributeToMass();
BodyConvex.bContributesToMass = false;
}
}
You can likely demonstrate this issue with even the basic ARealtimeMeshExample_Simple_Collision example, just change the CollisionBox.Center to be anywhere you like and you'll see that it's still pinned to 0,0,0, using the CVD (Chaos Visual Debugger) I was able to get a visualization of the problem, the image with the red circled body is using the code from before I apply transforms, the second without the red circled body is the second version of the function.
I'm unsure if this problem extends to the other body types, but it doesn't look like RMC explicitly does anything with those, so I can only assume they were never used?
Engine version: UE 5.8 (latest launcher build)
RMC version: Pro (Latest commit from Github)
So I must confess, I've been sat on this issue for nearly 2 years now and I've just not had the time to debug it and make a reasonable report so I was parked on UE5.4 and a version of RMC Pro from mid 2024 (commit hash:
c44a4f164c9f849031134403dd9baa08db682df1) what I was able to deduce seince having some time to debug, was the specific issue/s I've been running into started HERE.After the collision cooking was reworked, RMC seemingly stopped respecting
FRealtimeMeshCollisionConvex::Centerthe resulting cooked collision body is always placed at0,0,0of the component it's added to.For context, my project is a custom physics based vehicle game, players can attach arbitrary parts to their airships, engines, etc, when they do so, we we harvest out the collision bodies from the "part" over to the simple geometry of the airships "hull" (there's a specific reason we do this, it sucks, but it's mostly related to Unreal's character movement component being kinematically driven), the
Centerproperty was our way to pin that body to where it should be once copied over.Here's a code extract from how we used to do this body copying (scoped down to just the
ConvexHulls) from the 2024 commit hash I referenced above.Since the second commit I've referenced, it seems we now have to explicitly transform the vertices of the body to be where it should end up ourselves rather than relying on the
Centerproperty as we used to.You can likely demonstrate this issue with even the basic
ARealtimeMeshExample_Simple_Collisionexample, just change theCollisionBox.Centerto be anywhere you like and you'll see that it's still pinned to0,0,0, using the CVD (Chaos Visual Debugger) I was able to get a visualization of the problem, the image with the red circled body is using the code from before I apply transforms, the second without the red circled body is the second version of the function.I'm unsure if this problem extends to the other body types, but it doesn't look like RMC explicitly does anything with those, so I can only assume they were never used?