bevy_xpbd icon indicating copy to clipboard operation
bevy_xpbd copied to clipboard

Support for joints with with local frames (anchor position + rotation)

Open ollef opened this issue 2 years ago • 4 comments

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.

ollef avatar Nov 18 '23 21:11 ollef

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.

knexer avatar Nov 25 '23 02:11 knexer

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.

ollef avatar Nov 25 '23 19:11 ollef

+1 This would definitely be nice to have!

zArubaru avatar Mar 04 '24 07:03 zArubaru

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))])

HoutarouOreki avatar Jul 30 '24 00:07 HoutarouOreki