bevy_rapier icon indicating copy to clipboard operation
bevy_rapier copied to clipboard

RevoluteJoint ignores Transform

Open dankirkham opened this issue 2 years ago • 4 comments

Rapier cylinders are spawned with the flat side facing up. I need to rotate them about the x axis to make them stand up in order to function as a wheel. I am able to do this without the Rapier by providing a Transform to the PbrBundle. However when I try to attach the cylinder to a RevoluteJoint, this rotation is lost. I saw an example where you could provide a position to a ColliderBundle, but that appears to be a deprecated API. How I am I supposed to rotate the Collider?

let mut spawn_wheel = move |x, z| {
    let wheel_y = constants::WHEEL_THICKNESS;

    let joint = RevoluteJointBuilder::new(Vec3::Z)
        .local_anchor1(Vec3::new(x, -constants::TRUCK_HEIGHT / 3., 2. * z))
        .local_anchor2(Vec3::new(0., wheel_y, 0.));

    let transform = Transform {
        translation: Vec3::new(x, -constants::TRUCK_HEIGHT / 3., 2. * z),
        rotation: -Quat::from_rotation_x(PI / 2.),
        ..default()
    };

    child_builder.spawn((
        PbrBundle {
            mesh: mesh.clone(),
            material: material.clone(),
            transform,
            ..default()
        },
        RigidBody::Dynamic,
        Collider::cylinder(
            constants::WHEEL_THICKNESS / 2.,
            constants::WHEEL_DIAMETER / 2.,
        ),
        ImpulseJoint::new(child_builder.parent_entity(), joint),
    ));
};

Expected (joint/physics disabled):

Screen Shot 2023-12-07 at 1 30 12 PM

Actual (joints enabled):

Screen Shot 2023-12-07 at 1 31 31 PM

dankirkham avatar Dec 07 '23 19:12 dankirkham

I noticed that there was a rapier3d::geometry::ColliderBuilder and thought that I could use this to set the position of the Collider. Unfortunately, this is not the same as a bevy_rapier3d::geometry::Collider.

let rotation = nalgebra::UnitQuaternion::from_axis_angle(
    &nalgebra::Vector3::z_axis(),
    std::f32::consts::FRAC_PI_2,
);

let position = nalgebra::Isometry3 {
    rotation,
    ..Default::default()
};

let collider_builder = ColliderBuilder::new(SharedShape::cylinder(
    constants::WHEEL_THICKNESS / 2.,
    constants::WHEEL_DIAMETER / 2.,
));

// This yields a rapier3d::geometry::Collider which is
// NOT a bevy_rapier3d::geometry::Collider and thus
// does not implement Bundle.
let collider = collider_builder.position(position).build();

child_builder.spawn((
    PbrBundle {
        mesh: mesh.clone(),
        material: material.clone(),
        ..default()
    },
    RigidBody::Dynamic,
    collider,
    ImpulseJoint::new(child_builder.parent_entity(), joint),
));
error[E0277]: the trait bound `(MaterialMeshBundle<bevy::prelude::StandardMaterial>, bevy_rapier3d::dynamics::RigidBody, bevy_rapier3d::rapier3d::geometry::Collider, bevy_rapier3d::dynamics::ImpulseJoint): Bundle` is not satisfied

dankirkham avatar Dec 08 '23 03:12 dankirkham

It should work if you convert joint into a GenericJoint and adjust the second local basis.

let mut joint: GenericJoint = RevoluteJointBuilder::new(Vec3::Z)
    .local_anchor1(Vec3::new(x, -constants::TRUCK_HEIGHT / 3., 2. * z))
    .local_anchor2(Vec3::new(0., wheel_y, 0.))
    .into();
joint.set_local_basis2(Quat::from_rotation_z(std::f32::consts::FRAC_PI_2));

0x2a-42 avatar Jul 02 '24 16:07 0x2a-42

Is this considered a bug?

rparrett avatar Jul 22 '24 03:07 rparrett

The above workaround seemed very promising at first, but I was seeing some very bizarre behavior from my vehicle -- almost as if the motor/collider were applying their forces in their "original" orientation or something. My bike was behaving sort of like a "vibrobot".

Ultimately, I was able to work around this by burying the collider in the hierarchy, giving the collider and joint "separate transforms."

commands
    .spawn((
        TransformBundle::default(),
        RigidBody::Dynamic,
        ImpulseJoint::new(bike, joint),
    ))
    .with_children(|parent| {
        parent.spawn((
            TransformBundle::from_transform(Transform::from_rotation(rotation)),
            Collider::cylinder(wheel_thickness, wheel_radius),
        ));
    });

rparrett avatar Jul 23 '24 03:07 rparrett