Skip to content

Commit 5f687b0

Browse files
authored
Additional PinSlotJoint 2D implementation with DOF: 1 translation + 1 rotation (#775)
* Additional groove joint 2D implementation with 1 translation + 1 rotation * Conditional import for 2d feature flag * Groove joint 2d tests in testbed examples * Renamed GrooveJoint to PinSlotJoint * cargo fmt * Cross-reference to groove joint in Godot engine
1 parent eb62d2f commit 5f687b0

File tree

5 files changed

+368
-0
lines changed

5 files changed

+368
-0
lines changed

examples2d/all_examples2.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ mod joint_motor_position2;
2626
mod joints2;
2727
mod locked_rotations2;
2828
mod one_way_platforms2;
29+
mod pin_slot_joint2;
2930
mod platform2;
3031
mod polyline2;
3132
mod pyramid2;
@@ -66,6 +67,7 @@ pub fn main() {
6667
("One-way platforms", one_way_platforms2::init_world),
6768
("Platform", platform2::init_world),
6869
("Polyline", polyline2::init_world),
70+
("Pin Slot Joint", pin_slot_joint2::init_world),
6971
("Pyramid", pyramid2::init_world),
7072
("Restitution", restitution2::init_world),
7173
("Rope Joints", rope_joints2::init_world),

examples2d/pin_slot_joint2.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use rapier2d::prelude::*;
2+
use rapier_testbed2d::Testbed;
3+
4+
pub fn init_world(testbed: &mut Testbed) {
5+
/*
6+
* World
7+
*/
8+
let mut bodies = RigidBodySet::new();
9+
let mut colliders = ColliderSet::new();
10+
let mut impulse_joints = ImpulseJointSet::new();
11+
let multibody_joints = MultibodyJointSet::new();
12+
13+
/*
14+
* Ground
15+
*/
16+
let ground_size = 3.0;
17+
let ground_height = 0.1;
18+
19+
let rigid_body_floor = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height]);
20+
let floor_handle = bodies.insert(rigid_body_floor);
21+
let floor_collider = ColliderBuilder::cuboid(ground_size, ground_height);
22+
colliders.insert_with_parent(floor_collider, floor_handle, &mut bodies);
23+
24+
/*
25+
* Character we will control manually.
26+
*/
27+
let rigid_body_character =
28+
RigidBodyBuilder::kinematic_position_based().translation(vector![0.0, 0.3]);
29+
let character_handle = bodies.insert(rigid_body_character);
30+
let character_collider = ColliderBuilder::cuboid(0.15, 0.3);
31+
colliders.insert_with_parent(character_collider, character_handle, &mut bodies);
32+
33+
/*
34+
* Tethered cube.
35+
*/
36+
let rad = 0.4;
37+
38+
let rigid_body_cube =
39+
RigidBodyBuilder::new(RigidBodyType::Dynamic).translation(vector![1.0, 1.0]);
40+
let cube_handle = bodies.insert(rigid_body_cube);
41+
let cube_collider = ColliderBuilder::cuboid(rad, rad);
42+
colliders.insert_with_parent(cube_collider, cube_handle, &mut bodies);
43+
44+
/*
45+
* Rotation axis indicator ball.
46+
*/
47+
let rigid_body_ball =
48+
RigidBodyBuilder::new(RigidBodyType::Dynamic).translation(vector![1.0, 1.0]);
49+
let ball_handle = bodies.insert(rigid_body_ball);
50+
let ball_collider = ColliderBuilder::ball(0.1);
51+
colliders.insert_with_parent(ball_collider, ball_handle, &mut bodies);
52+
53+
/*
54+
* Fixed joint between rotation axis indicator and cube.
55+
*/
56+
let fixed_joint = FixedJointBuilder::new()
57+
.local_anchor1(point![0.0, 0.0])
58+
.local_anchor2(point![0.0, -0.4])
59+
.build();
60+
impulse_joints.insert(cube_handle, ball_handle, fixed_joint, true);
61+
62+
/*
63+
* Pin slot joint between cube and ground.
64+
*/
65+
let axis: nalgebra::Unit<
66+
nalgebra::Matrix<
67+
f32,
68+
nalgebra::Const<2>,
69+
nalgebra::Const<1>,
70+
nalgebra::ArrayStorage<f32, 2, 1>,
71+
>,
72+
> = UnitVector::new_normalize(vector![1.0, 1.0]);
73+
let pin_slot_joint = PinSlotJointBuilder::new(axis)
74+
.local_anchor1(point![2.0, 2.0])
75+
.local_anchor2(point![0.0, 0.4])
76+
.limits([-1.0, f32::INFINITY]) // Set the limits for the pin slot joint
77+
.build();
78+
impulse_joints.insert(character_handle, cube_handle, pin_slot_joint, true);
79+
80+
/*
81+
* Set up the testbed.
82+
*/
83+
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
84+
testbed.set_character_body(character_handle);
85+
testbed.look_at(point![0.0, 1.0], 100.0);
86+
}

src/dynamics/joint/generic_joint.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ bitflags::bitflags! {
6767
const LOCKED_REVOLUTE_AXES = Self::LIN_X.bits() | Self::LIN_Y.bits();
6868
/// The set of degrees of freedom locked by a prismatic joint.
6969
const LOCKED_PRISMATIC_AXES = Self::LIN_Y.bits() | Self::ANG_X.bits();
70+
/// The set of degrees of freedom locked by a pin slot joint.
71+
const LOCKED_PIN_SLOT_AXES = Self::LIN_Y.bits();
7072
/// The set of degrees of freedom locked by a fixed joint.
7173
const LOCKED_FIXED_AXES = Self::LIN_X.bits() | Self::LIN_Y.bits() | Self::ANG_X.bits();
7274
/// The set of degrees of freedom left free by a revolute joint.

src/dynamics/joint/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pub use self::generic_joint::*;
33
pub use self::impulse_joint::*;
44
pub use self::motor_model::MotorModel;
55
pub use self::multibody_joint::*;
6+
pub use self::pin_slot_joint::*;
67
pub use self::prismatic_joint::*;
78
pub use self::revolute_joint::*;
89
pub use self::rope_joint::*;
@@ -16,6 +17,7 @@ mod generic_joint;
1617
mod impulse_joint;
1718
mod motor_model;
1819
mod multibody_joint;
20+
mod pin_slot_joint;
1921
mod prismatic_joint;
2022
mod revolute_joint;
2123
mod rope_joint;

0 commit comments

Comments
 (0)