diff --git a/common/src/main/java/dev/ryanhcode/sable/api/physics/constraint/GenericConstraintConfiguration.java b/common/src/main/java/dev/ryanhcode/sable/api/physics/constraint/GenericConstraintConfiguration.java index 881d5569..c335b0af 100644 --- a/common/src/main/java/dev/ryanhcode/sable/api/physics/constraint/GenericConstraintConfiguration.java +++ b/common/src/main/java/dev/ryanhcode/sable/api/physics/constraint/GenericConstraintConfiguration.java @@ -23,9 +23,14 @@ public record GenericConstraintConfiguration( Vector3dc pos2, Quaterniondc orientation1, Quaterniondc orientation2, - Set lockedAxes + Set lockedAxes, + Set coupledAxes ) implements PhysicsConstraintConfiguration { + public GenericConstraintConfiguration(final Vector3dc pos1, final Vector3dc pos2, final Quaterniondc orientation1, final Quaterniondc orientation2, final Set lockedAxes) { + this(pos1, pos2, orientation1, orientation2, lockedAxes, EnumSet.noneOf(ConstraintJointAxis.class)); + } + public GenericConstraintConfiguration(final Vector3dc pos1, final Vector3dc pos2, final Quaterniondc orientation1, final Quaterniondc orientation2) { this(pos1, pos2, orientation1, orientation2, EnumSet.noneOf(ConstraintJointAxis.class)); } diff --git a/sable_rapier/src/main/java/dev/ryanhcode/sable/physics/impl/rapier/Rapier3D.java b/sable_rapier/src/main/java/dev/ryanhcode/sable/physics/impl/rapier/Rapier3D.java index 0ea77752..fe5009fe 100644 --- a/sable_rapier/src/main/java/dev/ryanhcode/sable/physics/impl/rapier/Rapier3D.java +++ b/sable_rapier/src/main/java/dev/ryanhcode/sable/physics/impl/rapier/Rapier3D.java @@ -415,6 +415,7 @@ public static native long addFreeConstraint(final long sceneHandle, * @param localOrientationZB the local orientation Z of the second object * @param localOrientationWB the local orientation W of the second object * @param lockedAxesMask bit mask of locked axes; bit {@code n} corresponds to {@link dev.ryanhcode.sable.api.physics.constraint.ConstraintJointAxis#ordinal()} + * @param coupledAxesMask bit mask of coupled axes; bit {@code n} corresponds to {@link dev.ryanhcode.sable.api.physics.constraint.ConstraintJointAxis#ordinal()} */ @ApiStatus.Internal public static native long addGenericConstraint(final long sceneHandle, @@ -434,7 +435,8 @@ public static native long addGenericConstraint(final long sceneHandle, double localOrientationYB, double localOrientationZB, double localOrientationWB, - int lockedAxesMask); + int lockedAxesMask, + int coupledAxesMask); /** * Sets the local frame on one side of a constraint. diff --git a/sable_rapier/src/main/java/dev/ryanhcode/sable/physics/impl/rapier/constraint/generic/RapierGenericConstraintHandle.java b/sable_rapier/src/main/java/dev/ryanhcode/sable/physics/impl/rapier/constraint/generic/RapierGenericConstraintHandle.java index 6d4f075c..027c2fc4 100644 --- a/sable_rapier/src/main/java/dev/ryanhcode/sable/physics/impl/rapier/constraint/generic/RapierGenericConstraintHandle.java +++ b/sable_rapier/src/main/java/dev/ryanhcode/sable/physics/impl/rapier/constraint/generic/RapierGenericConstraintHandle.java @@ -32,6 +32,11 @@ public class RapierGenericConstraintHandle extends RapierConstraintHandle implem lockedAxesMask |= 1 << axis.ordinal(); } + int coupledAxesMask = 0; + for (final ConstraintJointAxis axis : config.coupledAxes()) { + coupledAxesMask |= 1 << axis.ordinal(); + } + final long handle = Rapier3D.addGenericConstraint( sceneHandle, bodyA == null ? -1 : Rapier3D.getID(bodyA), @@ -50,7 +55,8 @@ public class RapierGenericConstraintHandle extends RapierConstraintHandle implem config.orientation2().y(), config.orientation2().z(), config.orientation2().w(), - lockedAxesMask + lockedAxesMask, + coupledAxesMask ); return new RapierGenericConstraintHandle(sceneHandle, handle); diff --git a/sable_rapier/src/main/rust/rapier/src/joints.rs b/sable_rapier/src/main/rust/rapier/src/joints.rs index 4d99b288..4ff3a25b 100644 --- a/sable_rapier/src/main/rust/rapier/src/joints.rs +++ b/sable_rapier/src/main/rust/rapier/src/joints.rs @@ -594,6 +594,7 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add local_q_z_b: jdouble, local_q_w_b: jdouble, locked_axes_mask: jint, + coupled_axes_mask: jint, ) -> SableJointHandle { with_handle(handle, |scene| { let mut sable_data = scene.sable_data.write().unwrap(); @@ -612,6 +613,7 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add }; let locked_axes = JointAxesMask::from_bits_truncate(locked_axes_mask as u8); + let coupled_axes = JointAxesMask::from_bits_truncate(coupled_axes_mask as u8); let rotation_a = Quat::from_xyzw( local_q_x_a as Real, @@ -626,10 +628,12 @@ pub extern "system" fn Java_dev_ryanhcode_sable_physics_impl_rapier_Rapier3D_add local_q_w_b as Real, ); - let mut joint = GenericJointBuilder::new(locked_axes).softness(SpringCoefficients::new( - JOINT_SPRING_FREQUENCY, - JOINT_SPRING_DAMPING_RATIO, - )); + let mut joint = GenericJointBuilder::new(locked_axes) + .coupled_axes(coupled_axes) + .softness(SpringCoefficients::new( + JOINT_SPRING_FREQUENCY, + JOINT_SPRING_DAMPING_RATIO, + )); joint.0.local_frame1.rotation = rotation_a; joint.0.local_frame2.rotation = rotation_b;