feat: implement new "small-steps" solver + joint improvements
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use crate::dynamics::joint::{GenericJoint, GenericJointBuilder, JointAxesMask};
|
||||
use crate::dynamics::{JointAxis, MotorModel};
|
||||
use crate::math::{Point, Real, UnitVector};
|
||||
use crate::math::{Point, Real};
|
||||
|
||||
use super::{JointLimits, JointMotor};
|
||||
use super::JointMotor;
|
||||
|
||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
@@ -14,12 +14,16 @@ pub struct RopeJoint {
|
||||
}
|
||||
|
||||
impl RopeJoint {
|
||||
/// Creates a new rope joint limiting the max distance between to bodies
|
||||
pub fn new() -> Self {
|
||||
let data = GenericJointBuilder::new(JointAxesMask::FREE_FIXED_AXES)
|
||||
/// Creates a new rope joint limiting the max distance between two bodies.
|
||||
///
|
||||
/// The `max_dist` must be strictly greater than 0.0.
|
||||
pub fn new(max_dist: Real) -> Self {
|
||||
let data = GenericJointBuilder::new(JointAxesMask::empty())
|
||||
.coupled_axes(JointAxesMask::LIN_AXES)
|
||||
.build();
|
||||
Self { data }
|
||||
let mut result = Self { data };
|
||||
result.set_max_distance(max_dist);
|
||||
result
|
||||
}
|
||||
|
||||
/// The underlying generic joint.
|
||||
@@ -62,30 +66,6 @@ impl RopeJoint {
|
||||
self
|
||||
}
|
||||
|
||||
/// The principal axis of the joint, expressed in the local-space of the first rigid-body.
|
||||
#[must_use]
|
||||
pub fn local_axis1(&self) -> UnitVector<Real> {
|
||||
self.data.local_axis1()
|
||||
}
|
||||
|
||||
/// Sets the principal axis of the joint, expressed in the local-space of the first rigid-body.
|
||||
pub fn set_local_axis1(&mut self, axis1: UnitVector<Real>) -> &mut Self {
|
||||
self.data.set_local_axis1(axis1);
|
||||
self
|
||||
}
|
||||
|
||||
/// The principal axis of the joint, expressed in the local-space of the second rigid-body.
|
||||
#[must_use]
|
||||
pub fn local_axis2(&self) -> UnitVector<Real> {
|
||||
self.data.local_axis2()
|
||||
}
|
||||
|
||||
/// Sets the principal axis of the joint, expressed in the local-space of the second rigid-body.
|
||||
pub fn set_local_axis2(&mut self, axis2: UnitVector<Real>) -> &mut Self {
|
||||
self.data.set_local_axis2(axis2);
|
||||
self
|
||||
}
|
||||
|
||||
/// The motor affecting the joint’s translational degree of freedom.
|
||||
#[must_use]
|
||||
pub fn motor(&self, axis: JointAxis) -> Option<&JointMotor> {
|
||||
@@ -95,9 +75,6 @@ impl RopeJoint {
|
||||
/// Set the spring-like model used by the motor to reach the desired target velocity and position.
|
||||
pub fn set_motor_model(&mut self, model: MotorModel) -> &mut Self {
|
||||
self.data.set_motor_model(JointAxis::X, model);
|
||||
self.data.set_motor_model(JointAxis::Y, model);
|
||||
#[cfg(feature = "dim3")]
|
||||
self.data.set_motor_model(JointAxis::Z, model);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -105,11 +82,6 @@ impl RopeJoint {
|
||||
pub fn set_motor_velocity(&mut self, target_vel: Real, factor: Real) -> &mut Self {
|
||||
self.data
|
||||
.set_motor_velocity(JointAxis::X, target_vel, factor);
|
||||
self.data
|
||||
.set_motor_velocity(JointAxis::Y, target_vel, factor);
|
||||
#[cfg(feature = "dim3")]
|
||||
self.data
|
||||
.set_motor_velocity(JointAxis::Z, target_vel, factor);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -122,11 +94,6 @@ impl RopeJoint {
|
||||
) -> &mut Self {
|
||||
self.data
|
||||
.set_motor_position(JointAxis::X, target_pos, stiffness, damping);
|
||||
self.data
|
||||
.set_motor_position(JointAxis::Y, target_pos, stiffness, damping);
|
||||
#[cfg(feature = "dim3")]
|
||||
self.data
|
||||
.set_motor_position(JointAxis::Z, target_pos, stiffness, damping);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -140,35 +107,26 @@ impl RopeJoint {
|
||||
) -> &mut Self {
|
||||
self.data
|
||||
.set_motor(JointAxis::X, target_pos, target_vel, stiffness, damping);
|
||||
self.data
|
||||
.set_motor(JointAxis::Y, target_pos, target_vel, stiffness, damping);
|
||||
#[cfg(feature = "dim3")]
|
||||
self.data
|
||||
.set_motor(JointAxis::Y, target_pos, target_vel, stiffness, damping);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the maximum force the motor can deliver.
|
||||
pub fn set_motor_max_force(&mut self, max_force: Real) -> &mut Self {
|
||||
self.data.set_motor_max_force(JointAxis::X, max_force);
|
||||
self.data.set_motor_max_force(JointAxis::Y, max_force);
|
||||
#[cfg(feature = "dim3")]
|
||||
self.data.set_motor_max_force(JointAxis::Z, max_force);
|
||||
self
|
||||
}
|
||||
|
||||
/// The limit maximum distance attached bodies can translate.
|
||||
/// The maximum distance allowed between the attached objects.
|
||||
#[must_use]
|
||||
pub fn limits(&self, axis: JointAxis) -> Option<&JointLimits<Real>> {
|
||||
self.data.limits(axis)
|
||||
pub fn max_distance(&self) -> Option<Real> {
|
||||
self.data.limits(JointAxis::X).map(|l| l.max)
|
||||
}
|
||||
|
||||
/// Sets the `[min,max]` limit distances attached bodies can translate.
|
||||
pub fn set_limits(&mut self, limits: [Real; 2]) -> &mut Self {
|
||||
self.data.set_limits(JointAxis::X, limits);
|
||||
self.data.set_limits(JointAxis::Y, limits);
|
||||
#[cfg(feature = "dim3")]
|
||||
self.data.set_limits(JointAxis::Z, limits);
|
||||
/// Sets the maximum allowed distance between the attached objects.
|
||||
///
|
||||
/// The `max_dist` must be strictly greater than 0.0.
|
||||
pub fn set_max_distance(&mut self, max_dist: Real) -> &mut Self {
|
||||
self.data.set_limits(JointAxis::X, [0.0, max_dist]);
|
||||
self
|
||||
}
|
||||
}
|
||||
@@ -190,8 +148,8 @@ impl RopeJointBuilder {
|
||||
/// Creates a new builder for rope joints.
|
||||
///
|
||||
/// This axis is expressed in the local-space of both rigid-bodies.
|
||||
pub fn new() -> Self {
|
||||
Self(RopeJoint::new())
|
||||
pub fn new(max_dist: Real) -> Self {
|
||||
Self(RopeJoint::new(max_dist))
|
||||
}
|
||||
|
||||
/// Sets whether contacts between the attached rigid-bodies are enabled.
|
||||
@@ -215,20 +173,6 @@ impl RopeJointBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the principal axis of the joint, expressed in the local-space of the first rigid-body.
|
||||
#[must_use]
|
||||
pub fn local_axis1(mut self, axis1: UnitVector<Real>) -> Self {
|
||||
self.0.set_local_axis1(axis1);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the principal axis of the joint, expressed in the local-space of the second rigid-body.
|
||||
#[must_use]
|
||||
pub fn local_axis2(mut self, axis2: UnitVector<Real>) -> Self {
|
||||
self.0.set_local_axis2(axis2);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the spring-like model used by the motor to reach the desired target velocity and position.
|
||||
#[must_use]
|
||||
pub fn motor_model(mut self, model: MotorModel) -> Self {
|
||||
@@ -270,10 +214,12 @@ impl RopeJointBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the `[min,max]` limit distances attached bodies can translate.
|
||||
/// Sets the maximum allowed distance between the attached bodies.
|
||||
///
|
||||
/// The `max_dist` must be strictly greater than 0.0.
|
||||
#[must_use]
|
||||
pub fn limits(mut self, limits: [Real; 2]) -> Self {
|
||||
self.0.set_limits(limits);
|
||||
pub fn max_distance(mut self, max_dist: Real) -> Self {
|
||||
self.0.set_max_distance(max_dist);
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user