The Equivalent Of NX_BF_FROZEN_ROT in PhysX 3.2.2

Is there a way to achieve the behavior that NX_BF_FROZEN_ROT_X, NX_BF_FROZEN_ROT_Y, NX_BF_FROZEN_ROT_Z and NX_BF_FROZEN_ROT provided in PhysX 2.8? I’ve tried to continually force the angular velocity to zero but that doesn’t seem to work.

Thanks

Any idea?

Essentially I’m wondering how to create a rigid dynamic body where it’s rotation is locked along all or an arbitrary axis.

Thanks!

Have you tried using a D6 joint with locked axes?

Hello HaiLocLu,

I thought about trying that but I haven’t yet as it is my understanding that a joint has to be between two actors. Perhaps there is a way to constrain rotation in the global frame without an additional actor?

From the docs…

Use a NULL pointer here to indicate an implicit actor representing the immovable global reference frame.

Hmmm! I will try this… thank you HaiLocLu!

Okay so it’s been a while and I’m revisiting this issue.

Does anyone know a way to replicate the behavior of NX_BF_FROZEN_ROT_X /Y /Z flags that were available in PhysX 2.8.4?

I’ve tried all sorts of hacks as well as the 6 DOF constraint. The 6 DOF can topple over under moderate forces.

Any ideas would be helpful. Thank you

Hi,

Sorry for the delay in response. Could you tell me more about your use case? Why not just ignore the rotational component of the PxRigidDynamic’s global pose, and drive your graphics object transform using only the position coordinates? Or is it that you require a collision shape to maintain a specific orientation, but move about the world linearly? Have you tried calling setGlobalPose with each frame, to override only the angular components?

Thanks,
Mike

Hi.

Look at this post: Missing features in 3 series compared to 2? - Physics Modeling (closed) - NVIDIA Developer Forums

Here I did a small decription how can use the D6 Joints - for locking the unneeded rotations.
But of course, you already use them.
As MikePhysX already said, it would be easier for us to know what you are trying to archieve with it.
I guess the direct set of the location could work - but you have to make sure that your positions
arent in other physx shapes. ( Thus … I recommend the D6 Joint )

Here is the comment of setGlobalPose:
Even when moving dynamic actors, exercise restraint in making use of this method.
Where possible, avoid:

  • moving actors into other actors, thus causing interpenetration (an invalid physical state)
  • moving an actor that is connected by a joint to another away from the other (thus causing joint error)

Of course, you could raise the kinematics flag to move your actor with setKinematic target.
( Look at the setGlobalPose comment, its the recommend way to do it [without joints…] )

Hi guys…

What I have done in the past for a frame is

  • move the character controller normally with ->move()
  • position a proxy dynamic capsule with the same dimensions as the controller at the controllers location
  • Move kinematic platforms \ pushers
  • step the physic sim
  • retrieve the position of the dynamic proxy capsule and store it back in the character controller

This led to a robust solution in 2.8.4 where my character could ride any platform … be pushed by multiple kinematics at the same time. Even ride arbitrary kinematic trimesh shapes.

Sadly a D6 joint doesn’t ensure a purely translational penetration resolve and will tip over under these kind of forces. Check out this programmer art.

External Media

Any ideas on how I could otherwise robustly push a character controller? Not just ride it.
Thanks!

Same issue here.

Basically, I have a need to lock an actor on one or more of its local axes so that it can not tumble/rotate on x, y or z selectively.

I can get the D6 joint to lock all rotations by setting twist to Locked, but that is not enough control since I may want only rotations on the Z axis to occur, but nothing else.

Any other suggestions on this problem? Right now my only solution will be to forcefully stop rotations and add corrective forces myself.

(@Nvidia: Multiply codetags still wont work!)

Hi,

you can lock each axis selectivley by using mJoint->setMotion(…)
You could read it in the PhysXGuide and in the header of the PxD6Joint too.

First you have to create a joint which is attached to the actor:

PxD6Joint* mJoint = PxD6JointCreate(*mPhysic->getSDK(), mActor, PxTransform::createIdentity(), nullptr, mActor->getGlobalPose());

After the creation, you could lock or limit or set them free for each axis you need.
This code will lock any rotation. The mActor can still move around.
Default settings are that every axis is locked - so you have to unlock it.

mJoint->setMotion(PxD6Axis::eX,PxD6Motion::eFREE); // Movement on X allowed
mJoint->setMotion(PxD6Axis::eY,PxD6Motion::eFREE); // Movement on Y allowed
mJoint->setMotion(PxD6Axis::eZ,PxD6Motion::eFREE); // Movement on Z allowed

This will lock a rotation around the X axis:
mJoint->setMotion(PxD6Axis::eSWING2,PxD6Motion::eLOCKED);

For the Y rotation axis:
mJoint->setMotion(PxD6Axis::eSWING1,PxD6Motion::eLOCKED);

For the Z rotation axis:
mJoint->setMotion(PxD6Axis::eTWIST,PxD6Motion::eLOCKED);

You could even limit the rotation around an axis - if you need it.

In most cases this will work fine - but with the wrong time stepping, under circumstances
with different forces which is applied - the joints wont work correct for the “position” locking.

I didnt had any issues with locked rotation which can still rotate under forces - but I didnt test enough.

I guess it was when I tested the “position lock” for a dynamic actor and try to push it with a kinematic actor away.
( It was just only a test - better method for it is to raise kinematic flag for the dynamic actor)