I am not familiar with “setMotion(axis, PxD6Motion::eFREE)” to be able to lock the joint as it commands it to be free. You probably also use “setMotion(axis, PxD6Motion:: eLOCKED)”. The later indeed locks the joint to the reference orientation.
We leave joints at eFree or eLimited and lock joints in place with the joint drive. For the joint drive we calculate the current relative position off the actors (as PhysX 3.x does not provide as simple function for that grrrr….). Then we use:
-setdrive(PXD6Drive, PxD6JointDrive) (set the stiffness and damping gains for one axis)
-setDriveVelocity(Drive_pos_vel,Drive_rot_vel) (set the desired velocity)
- setDrivePosition(DriveTransform) (set the desired orientation).
To get the current relative position off the actors (DriveTransform) we use the following code (you should correct naming and references yourself):
PxTransform a0_lp = JT->getLocalPose(PxJointActorIndex::eACTOR0);
PxTransform a1_lp = JT->getLocalPose(PxJointActorIndex::eACTOR1);
PxTransform a1_if_jt_at_o = a1_lp;
/// where is the actor now ? (pretending that the joint is the origin)
PxTransform T0 = Actor0->getGlobalPose();
PxTransform T1 = Actor1->getGlobalPose();
PxTransform a1_if_jt_at_o_now = (T0.getInverse()*T1).getInverse()*a0_lp;
// find the differenc between the original and current transfom of actor1
DriveTransform = (a1_if_jt_at_o.getInverse()*a1_if_jt_at_o_now).getInverse();