mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
added ball joint motor for 3d
This commit is contained in:
@@ -1806,27 +1806,30 @@ impl PhysicsWorld {
|
||||
convert_joint_params(v, native.data.local_frame1, native.data.local_frame2)
|
||||
});
|
||||
joint.motor_params.try_sync_model(|v|{
|
||||
// The free axis is defined to be the x axis for both prismatic and revolute joints in fyrox.
|
||||
// For prismatic and revolute joints, the free axis is defined to be the x axis.
|
||||
// If you want the joint to translate / rotate along a different axis, you can rotate the joint itself.
|
||||
let joint_axis = match joint.params.get_value_ref(){
|
||||
JointParams::PrismaticJoint(_) => JointAxis::LinX,
|
||||
JointParams::RevoluteJoint(_) => JointAxis::AngX,
|
||||
let joint_axes: &[JointAxis] = match joint.params.get_value_ref(){
|
||||
JointParams::PrismaticJoint(_) => &[JointAxis::LinX][..], // slice the array to unify arrays of different lengths.
|
||||
JointParams::RevoluteJoint(_) => &[JointAxis::AngX][..],
|
||||
JointParams::BallJoint(_) => &[JointAxis::AngX, JointAxis::AngY, JointAxis::AngZ][..],
|
||||
_ => {
|
||||
Log::warn("Try to modify motor parameters for unsupported joint type, this operation will be ignored.");
|
||||
return;
|
||||
}
|
||||
};
|
||||
// Force based motor model is better in the Fyrox's context
|
||||
native.data.set_motor_model(joint_axis, rapier3d::prelude::MotorModel::ForceBased);
|
||||
let JointMotorParams {
|
||||
target_vel,
|
||||
target_pos,
|
||||
stiffness,
|
||||
damping,
|
||||
max_force
|
||||
} = v;
|
||||
native.data.set_motor(joint_axis, target_pos, target_vel, stiffness, damping);
|
||||
native.data.set_motor_max_force(joint_axis, max_force);
|
||||
for joint_axis in joint_axes {
|
||||
// Force based motor model is better in the Fyrox's context
|
||||
native.data.set_motor_model(*joint_axis, rapier3d::prelude::MotorModel::ForceBased);
|
||||
let JointMotorParams {
|
||||
target_vel,
|
||||
target_pos,
|
||||
stiffness,
|
||||
damping,
|
||||
max_force
|
||||
} = v;
|
||||
native.data.set_motor(*joint_axis, target_pos, target_vel, stiffness, damping);
|
||||
native.data.set_motor_max_force(*joint_axis, max_force);
|
||||
}
|
||||
// wake up the bodies connected to the joint to ensure they respond to the motor changes immediately
|
||||
// however, the rigid bodies may fall asleep any time later unless Joint::set_motor_* functions are called periodically,
|
||||
// or the rigid bodies are set to cannot sleep
|
||||
|
||||
@@ -402,7 +402,7 @@ impl Joint {
|
||||
/// # Arguments
|
||||
/// * `force` - The maximum force this motor can deliver.
|
||||
/// * `max_vel` - The target velocity of the motor.
|
||||
/// * `damping` - Controls how smoothly the motor will reach the target velocity. A higher damping value will result in a smoother transition to the target velocity.
|
||||
/// * `damping` - Penalizes high velocities to avoid overshooting the target velocity. A higher damping value will result in a smoother transition to the target velocity.
|
||||
/// # Errors
|
||||
/// If the joint is not a [`PrismaticJoint`], this function will do nothing and return an Err.
|
||||
/// # Notice
|
||||
@@ -436,7 +436,7 @@ impl Joint {
|
||||
/// # Arguments
|
||||
/// * `torque` - The maximum torque this motor can deliver.
|
||||
/// * `max_angular_vel` - The target angular velocity of the motor.
|
||||
/// * `damping` - Controls how smoothly the motor will reach the target angular velocity. A higher damping value will result in a smoother transition to the target angular velocity.
|
||||
/// * `damping` - Penalizes high angular velocities to avoid overshooting the target angular velocity. A higher damping value will result in a smoother transition to the target angular velocity.
|
||||
/// # Errors
|
||||
/// If the joint is not a [`RevoluteJoint`], this function will do nothing and return an Err.
|
||||
/// # Notice
|
||||
@@ -473,7 +473,7 @@ impl Joint {
|
||||
/// * `target_position` - The target position that the joint will try to reach, can be negative.
|
||||
/// * `stiffness` - Controls how fast the joint will try to reach the target position.
|
||||
/// * `max_force` - The maximum force this motor can deliver.
|
||||
/// * `damping` - Controls how much the joint will resist motion when it is moving towards the target position.
|
||||
/// * `damping` - Penalizes high velocities to avoid overshooting the target position. A higher damping value will result in a smoother transition to the target position.
|
||||
/// # Errors
|
||||
/// If the joint is not a [`PrismaticJoint`], the function will do nothing and return an Err.
|
||||
/// # Notice
|
||||
@@ -511,7 +511,7 @@ impl Joint {
|
||||
/// * `target_angle` - The target angle **in radians** that the joint will try to reach, can be negative. If the value is greater than 2π or less than -2π, the joint will turn multiple times to reach the target angle.
|
||||
/// * `stiffness` - Controls how fast the joint will try to reach the target angle.
|
||||
/// * `max_torque` - The maximum torque this motor can deliver.
|
||||
/// * `damping` - Controls how much the joint will resist motion when it is moving towards the target angle.
|
||||
/// * `damping` - Penalizes high angular velocities to avoid overshooting the target angle. A higher damping value will result in a smoother transition to the target angle.
|
||||
/// # Errors
|
||||
/// If the joint is not a [`RevoluteJoint`], the function will do nothing and return an Err.
|
||||
/// # Notice
|
||||
@@ -540,17 +540,58 @@ impl Joint {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Disables the motor of the joint assuming it is a [`RevoluteJoint`] or [`PrismaticJoint`].
|
||||
/// Makes the [`BallJoint`] to restore its original orientation with motor torque.
|
||||
///
|
||||
/// Acts as a flexible fixed joint that tolerates some angular movement and tries to restore the original orientation.
|
||||
///
|
||||
/// For flexible fixed joints that tolerate some translational movement, consider using a [`PrismaticJoint`] and call [`Self::set_motor_target_position_as_prismatic`].
|
||||
///
|
||||
/// The motor torque is uniform across all three axes of the joint.
|
||||
///
|
||||
/// /// Call [`Self::disable_motor`] to stop the motor and remove the spring effect.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `stiffness` - Controls how fast the joint will try to restore its original orientation.
|
||||
/// * `max_torque` - The maximum torque this motor can deliver.
|
||||
/// * `damping` - Penalizes high angular velocities to avoid overshooting the original orientation. A higher damping value will result in a smoother transition to the original orientation.
|
||||
/// # Errors
|
||||
/// If the joint is not a [`BallJoint`], the function will do nothing and return an Err.
|
||||
/// # Notice
|
||||
/// The rigid bodies attached to the joint may fall asleep anytime regardless whether the motor is enabled or not.
|
||||
///
|
||||
/// To avoid this behavior, call this function periodically or call [`RigidBody::set_can_sleep`] on the rigid bodies with "false".
|
||||
pub fn set_motor_resistive_torque_as_ball(
|
||||
&mut self,
|
||||
stiffness: f32,
|
||||
max_torque: f32,
|
||||
damping: f32,
|
||||
) -> Result<(), String> {
|
||||
let JointParams::BallJoint(_) = self.params() else {
|
||||
return Err("Joint is not a BallJoint".to_string());
|
||||
};
|
||||
let motor_params = JointMotorParams {
|
||||
target_vel: 0.0,
|
||||
target_pos: 0.0,
|
||||
stiffness,
|
||||
damping,
|
||||
max_force: max_torque,
|
||||
};
|
||||
// retrieving the mutable reference to the joint params will cause the engine to do additional calculations to reflect changes to the physics engine.
|
||||
self.set_motor_params(motor_params);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Disables the motor of the joint assuming it is a [`RevoluteJoint`], [`PrismaticJoint`] or [`BallJoint`].
|
||||
///
|
||||
/// After this call, the joint will no longer apply any motor force or torque to the connected bodies.
|
||||
/// # Errors
|
||||
/// If the joint is not a [`RevoluteJoint`] or [`PrismaticJoint`], the function will do nothing and return an Err.
|
||||
/// If the joint is not a [`RevoluteJoint`], [`PrismaticJoint`] or [`BallJoint`], the function will do nothing and return an Err.
|
||||
pub fn disable_motor(&mut self) -> Result<(), String> {
|
||||
if !matches!(
|
||||
self.params(),
|
||||
JointParams::RevoluteJoint(_) | JointParams::PrismaticJoint(_)
|
||||
JointParams::RevoluteJoint(_) | JointParams::PrismaticJoint(_) | JointParams::BallJoint(_)
|
||||
) {
|
||||
return Err("Joint is not a RevoluteJoint or PrismaticJoint".to_string());
|
||||
return Err("Joint is not a RevoluteJoint, PrismaticJoint or BallJoint".to_string());
|
||||
}
|
||||
let motor_params = JointMotorParams {
|
||||
target_vel: 0.0,
|
||||
|
||||
Reference in New Issue
Block a user