Hi, I’m trying to generate box components at each face of a dynamic mesh at runtime, however, setting the box component extents is really throwing me off. I’m generating the box components successfully and setting the transforms of the components to align with their corresponding mesh faces, and I currently get this:
As you can see, two boxes align to the cube mesh as intended, and two appear to be rotated by 90 degrees. The box extent vectors are points in world space derived from the vertices of the dynamic mesh component (the blue cube), shown here as the magenta spheres. I’m representing the transform of each box component by drawing a debug coordinate at each box origin.
For clarity, I want the box components to align to the mesh faces. Something like this:
I’m doing this dynamically at runtime because if a user edits the mesh, the box components should be regenerated to match the new mesh dimensions and faces including if a mesh face is not orthogonal. So ideally this should work for shapes like an octagonal prism, etc.
My question is: Why are two of the box components not matching up with their extents? Do I need to do something to the extents vector to translate it from world space to the local component space?
Here’s my function for generating the box components (sorry for the comments, I’ve been trying all sorts of things):
void ABuildActor::GenerateCollisionBoxes(TMap<int32, FDynamicMeshPolygroupDataStruct> PolygroupData)
{
if (MeshComponent && GetWorld())
{
for (TPair<int32, FDynamicMeshPolygroupDataStruct>& Pair : PolygroupDataStructs)
{
if (Pair.Value.PolygroupNormal.Z == 0)
{
FRotator BoxRotation = UKismetMathLibrary::MakeRotFromX(Pair.Value.PolygroupNormal) - GetActorRotation();
BoxRotation.Yaw -= 90;
FVector BoxTranslation = Pair.Value.PolygroupCentroid - GetActorLocation();
FTransform BoxTransform(BoxRotation, BoxTranslation);
UBoxComponentWithID* CollisionBox = Cast<UBoxComponentWithID>(AddComponentByClass(UBoxComponentWithID::StaticClass(), false, BoxTransform, false));
FVector BoxExtent((Pair.Value.PolygroupVertices[0] - Pair.Value.PolygroupCentroid) + (Pair.Value.PolygroupNormal * 50.0f));
//FVector LocalBoxExtent = UKismetMathLibrary::InverseTransformLocation(BoxTransform, BoxExtent);
//FVector LocalBoxExtent = UKismetMathLibrary::TransformLocation(BoxTransform, BoxExtent);
// box transform, rotation, extents, etc.
CollisionBox->SetWorldLocation(Pair.Value.PolygroupCentroid);
//CollisionBox->SetRelativeRotation(FRotator::ZeroRotator);
CollisionBox->SetBoxExtent(BoxExtent);
//UE_LOG(LogTemp, Warning, TEXT("Box Transform: %s"), *CollisionBox->GetRelativeTransform().ToString());
// box identity, etc.
CollisionBox->SetGenerateOverlapEvents(true);
CollisionBox->SetCollisionEnabled(ECollisionEnabled::NoCollision);
CollisionBox->SetBoxID(Pair.Key);
CollisionBox->SetBoxNormal(Pair.Value.PolygroupNormal);
CollisionBox->bHiddenInGame = false;
// add to list
BoxComponents.Add(CollisionBox);
// bind overlap functions to box component
CollisionBox->OnComponentBeginOverlap.AddDynamic(this, &ABuildActor::OnOverlapBegin);
CollisionBox->OnComponentEndOverlap.AddDynamic(this, &ABuildActor::OnOverlapEnd);
}
}
}
}
Any insight would be much appreciated!