Support for joints with with local frames (anchor position + rotation)
Currently, joints that constrain the rotation of objects (e.g. FixedJoint or PrismaticJoint) seem to constrain the rotation of the bodies to be the same, and we have to use hacks to join bodies with different relative rotations.
For example, this might come up if we want to add a joint between a vehicle's body and a cylindrical wheel. A cylinder's default rotation is to have the flat side up, which means that it's forced to this orientation when adding a joint between the body and the wheel.
It would be nice to have e.g. with_local_frame methods for joints, that take an isometry (rotation + translation), mirroring the with_local_anchor methods that are currently there.
I needed this and ended up hacking support into a copy of FixedJoint in my own test project: https://github.com/knexer/bevy-vr-test/blob/main/src/fixed_joint_2.rs
I went with a different API that was easier for me to reason about, and works well for my use case - specifying a rotation offset from body 1 to body 2. Not sure which interface (relative offset for the joint or local frames for each body) would be more intuitive for most people - tbh I'm not even sure they're equally expressive.
That looks quite intuitive to me too, and it seems to me like that would be equally expressive, though I'm also not entirely sure. For what it's worth, it looks like Rapier uses an isometry per body.
+1 This would definitely be nice to have!
If anyone else here can't figure it out, you can create a Collider::compound to have a rotated cylinder:
First, create a transform to rotate along an axis by 90 degrees:
let tyre_rotation_transform = Transform {
rotation: Quat::from_rotation_z(90.0_f32.to_radians()),
..Default::default()
};
Then use it to create a compound collider with a rotated cylinder shape:
Collider::compound(vec![(Vec3::ZERO, tyre_rotation_transform, Collider::cylinder(tyre_radius, tyre_width))])