So I am working on my custom Physics Handle, which derives from USceneComponent. I copied a lot of code from Epic’s Physics Handle.
I have developed the following functions:
void UVRPhysicsHandle::RotateGrabbedComponentToTheRight(float Degrees)
{
if (!GrabbedComponent || FMath::IsNearlyZero(Degrees)) { return; }
RotateGrabbedComponent(FQuat(GetUpVector(), FMath::DegreesToRadians(Degrees)));
}
void UVRPhysicsHandle::RotateGrabbedComponent(const FQuat& Rotation)
{
if (!GrabbedComponent || !HandleData) { return; }
PxTransform PoseInv = HandleData->getLocalPose(physx::PxJointActorIndex::eACTOR1).getInverse();
PoseInv = PoseInv.transform(PxTransform(U2PQuat(Rotation)));
HandleData->setLocalPose(physx::PxJointActorIndex::eACTOR1, PoseInv.getInverse());
// problem: Pose is local, but Rotation is global space
}
HandleData is a physx::PxD6Joint*
The result is that the PxD6Joint rotates the GrabbedComponent (PxJointActorIndex::eACTOR1) around its origin. But the rotation should happen relative to my Physics Handle Component. If I pass in a global FQuat
RotateGrabbedComponent(FQuat(FVector(0.f, 0.f, 1.f), FMath::DegreesToRadians(Degrees)));
instead of
RotateGrabbedComponent(FQuat(GetUpVector(), FMath::DegreesToRadians(Degrees)));
The Physics Handle rotates the GrabbedComponent in the GrabbedComponent’s local space.
Any ideas?
Edit: I thought it might be worth mentioning, that getLocalPose() essentially returns a Transform from the PxActor to the Joint. In my case the Joint location is Identical to the other PxActor’s location, because the other PxActor’s local pose is the Identity Transform.