RBD Solver is not updating packed instrinsic transform!

   148   1   1
User Avatar
Member
2 posts
Joined: Jan. 2025
Offline
I’m working inside an RBD Solver / Bullet DOP and trying to blend rigid body rotations toward a target orientation (similar to MOPs Apply Attributes behavior). I’m confused about the relationship between @orient, packed transforms, and the solver’s internal state.

When I run the following code inside a point Wrangle inside the RBD solver:

p@orient = slerp(@orient, targetorient, mops);

Edit: I also tried writing the matrix directly using setprimintrinsic but the matrix is still not fully written.

I want to Reliably blend a rigid body’s rotation toward a target orientation and Have the actual packed transform fully align.

The orient attribute updates correctly in the Geometry Spreadsheet and The rotation visually changes partially. However, the packed primitive transform (3×3 / 4×4) never fully aligns to the target(Rotation). Updating orient does not appear to rebuild the solver’s transform completely. Same logic works perfectly in SOPs. Disabling collisions does not change the result.

Why does writing to @orient inside the RBD solver update the attribute but not the rigid body’s full actual transform?

Thanks

Any clarification on how Bullet treats @orient vs internal transforms, and best-practice ways to drive rotation (especially snapping cases), would be greatly appreciated.
Edited by dfnqvirtual - Feb. 15, 2026 04:20:59
User Avatar
Member
411 posts
Joined: April 2017
Offline
The orient attribute in Bullet is defined relative to the starting transform of each piece, as defined by the restxform attribute that's automatically created on the first timestep. So if your rest transform is something like a 90 degree rotation around X and your orient attribute is also a 90 degree rotation around X, the RBD solver will add that rotation to the piece making it snap to a 180 degree rotation around X on the first timestep.

If you want to force the RBD to match a world space orientation defined elsewhere, you could convert the restxform attribute to a quaternion, then multiply your goal orientation by that rest orientation. Depending on how you're defining these terms that should get you an orientation in world space that you can slerp. Then you can convert that blended orientation back into a space that Bullet will understand by multiplying that result against the inverse of the rest orientation, which you could then bind to the orient attribute for the solver to read.

You can always update the intrinsic transforms directly if you prefer, but it's significantly slower to do so.
Edited by toadstorm - yesterday 15:15:37
MOPs (Motion Operators for Houdini): http://www.motionoperators.com [www.motionoperators.com]
  • Quick Links