joint limits improvements

- separate limits per axis for ball joint
- switch to enable\disable joint limits
This commit is contained in:
Dmitry
2022-07-12 20:13:50 +03:00
parent 15cd602cb9
commit ed31512d57
8 changed files with 160 additions and 63 deletions
+12 -3
View File
@@ -45,13 +45,21 @@ pub fn handle_joint_property_changed(
pub fn handle_ball_joint(args: &PropertyChanged, handle: Handle<Node>) -> Option<SceneCommand> {
handle_property_changed!(args, handle,
BallJoint::LIMITS_ANGLES => SetBallJointLimitsCommand
BallJoint::X_LIMITS_ANGLES => SetBallJointXLimitsCommand,
BallJoint::X_LIMITS_ENABLED => SetBallJointXLimitsEnabledCommand,
BallJoint::Y_LIMITS_ANGLES => SetBallJointYLimitsCommand,
BallJoint::Y_LIMITS_ENABLED => SetBallJointYLimitsEnabledCommand,
BallJoint::Z_LIMITS_ANGLES => SetBallJointZLimitsCommand,
BallJoint::Z_LIMITS_ENABLED => SetBallJointZLimitsEnabledCommand
)
}
pub fn handle_revolute_joint(args: &PropertyChanged, handle: Handle<Node>) -> Option<SceneCommand> {
handle_property_changed!(args, handle,
RevoluteJoint::LIMITS => SetRevoluteJointLimitsCommand
RevoluteJoint::LIMITS => SetRevoluteJointLimitsCommand,
RevoluteJoint::LIMITS_ENABLED => SetRevoluteJointLimitsEnabledCommand
)
}
@@ -60,7 +68,8 @@ pub fn handle_prismatic_joint(
handle: Handle<Node>,
) -> Option<SceneCommand> {
handle_property_changed!(args, handle,
PrismaticJoint::LIMITS => SetPrismaticJointLimitsCommand
PrismaticJoint::LIMITS => SetPrismaticJointLimitsCommand,
PrismaticJoint::LIMITS_ENABLED => SetPrismaticJointLimitsEnabledCommand
)
}
@@ -43,7 +43,8 @@ pub fn handle_joint2d_property_changed(
pub fn handle_ball_joint(args: &PropertyChanged, handle: Handle<Node>) -> Option<SceneCommand> {
handle_property_changed!(args, handle,
BallJoint::LIMITS_ANGLES => SetBallJointLimitsCommand
BallJoint::LIMITS_ANGLES => SetBallJointLimitsCommand,
BallJoint::LIMITS_ENABLED => SetBallJointLimitsEnabledCommand
)
}
@@ -52,7 +53,8 @@ pub fn handle_prismatic_joint(
handle: Handle<Node>,
) -> Option<SceneCommand> {
handle_property_changed!(args, handle,
PrismaticJoint::LIMITS => SetPrismaticJointLimitsCommand
PrismaticJoint::LIMITS => SetPrismaticJointLimitsCommand,
PrismaticJoint::LIMITS_ENABLED => SetPrismaticJointLimitsEnabledCommand
)
}
+10 -1
View File
@@ -23,9 +23,18 @@ macro_rules! define_joint_variant_command {
}
define_joint_variant_command! {
SetBallJointLimitsCommand(Range<f32>): BallJoint, limits_angles, "Set Ball Joint Limits";
SetBallJointXLimitsCommand(Range<f32>): BallJoint, x_limits_angles, "Set Ball Joint X Limits";
SetBallJointXLimitsEnabledCommand(bool): BallJoint, x_limits_enabled, "Set Ball Joint X Limits Enabled";
SetBallJointYLimitsCommand(Range<f32>): BallJoint, y_limits_angles, "Set Ball Joint Y Limits";
SetBallJointYLimitsEnabledCommand(bool): BallJoint, y_limits_enabled, "Set Ball Joint Y Limits Enabled";
SetBallJointZLimitsCommand(Range<f32>): BallJoint, z_limits_angles, "Set Ball Joint Z Limits";
SetBallJointZLimitsEnabledCommand(bool): BallJoint, z_limits_enabled, "Set Ball Joint Z Limits Enabled";
SetRevoluteJointLimitsCommand(Range<f32>): RevoluteJoint, limits, "Set Revolute Joint Limits";
SetRevoluteJointLimitsEnabledCommand(bool): RevoluteJoint, limits_enabled, "Set Revolute Joint Limits Enabled";
SetPrismaticJointLimitsCommand(Range<f32>): PrismaticJoint, limits, "Set Prismatic Joint Limits";
SetPrismaticJointLimitsEnabledCommand(bool): PrismaticJoint, limits_enabled, "Set Prismatic Joint Limits Enabled";
}
define_swap_command! {
+3
View File
@@ -24,7 +24,10 @@ macro_rules! define_joint_variant_command {
define_joint_variant_command! {
SetBallJointLimitsCommand(Range<f32>): BallJoint, limits_angles, "Set Ball Joint Limits";
SetBallJointLimitsEnabledCommand(bool): BallJoint, limits_enabled, "Set Ball Joint Limits Enabled";
SetPrismaticJointLimitsCommand(Range<f32>): PrismaticJoint, limits, "Set Prismatic Joint Limits";
SetPrismaticJointLimitsEnabledCommand(bool): PrismaticJoint, limits_enabled, "Set Prismatic Joint Limits";
}
define_swap_command! {
+18 -2
View File
@@ -31,7 +31,13 @@ use std::{
/// pendulum, etc.
#[derive(Clone, Debug, Visit, PartialEq, Inspect)]
pub struct BallJoint {
/// The maximum angle allowed between the two limit axes in world-space.
/// Whether angular limits are enabled or not. Default is `false`
#[inspect(description = "Whether angular limits are enabled or not.")]
#[visit(optional)] // Backward compatibility
pub limits_enabled: bool,
/// Allowed angles range for the joint (in radians).
#[inspect(description = "Allowed angles range for the joint (in radians).")]
#[visit(optional)] // Backward compatibility
pub limits_angles: Range<f32>,
}
@@ -39,6 +45,7 @@ pub struct BallJoint {
impl Default for BallJoint {
fn default() -> Self {
Self {
limits_enabled: false,
limits_angles: -std::f32::consts::PI..std::f32::consts::PI,
}
}
@@ -53,7 +60,15 @@ pub struct FixedJoint;
/// translations along one axis. The real world example is a sliders that used to support drawers.
#[derive(Clone, Debug, Visit, PartialEq, Inspect)]
pub struct PrismaticJoint {
/// The min an max relative position of the attached bodies along this joint's axis.
/// Whether linear limits along local X axis of the joint are enabled or not. Default is `false`
#[inspect(
description = "Whether linear limits along local X axis of the joint are enabled or not."
)]
#[visit(optional)] // Backward compatibility
pub limits_enabled: bool,
/// Allowed linear distance range along local X axis of the joint.
#[inspect(description = "Allowed linear distance range along local X axis of the joint.")]
#[visit(optional)] // Backward compatibility
pub limits: Range<f32>,
}
@@ -61,6 +76,7 @@ pub struct PrismaticJoint {
impl Default for PrismaticJoint {
fn default() -> Self {
Self {
limits_enabled: false,
limits: -std::f32::consts::PI..std::f32::consts::PI,
}
}
+25 -18
View File
@@ -1,18 +1,18 @@
//! Scene physics module.
use crate::scene::dim2::joint::JointParams;
use crate::{
core::algebra::Vector2,
core::variable::VariableFlags,
core::{
algebra::{Isometry2, Matrix4, Point2, Translation2, UnitComplex, UnitQuaternion, Vector3},
algebra::{Isometry3, Point3, Rotation3, Translation3},
algebra::{
Isometry2, Isometry3, Matrix4, Point2, Point3, Rotation3, Translation2, Translation3,
UnitComplex, UnitQuaternion, Vector2, Vector3,
},
arrayvec::ArrayVec,
color::Color,
inspect::{Inspect, PropertyInfo},
instant,
math::Matrix4Ext,
pool::Handle,
variable::VariableFlags,
visitor::prelude::*,
BiDirHashMap,
},
@@ -20,7 +20,7 @@ use crate::{
self,
collider::{self},
debug::{Line, SceneDrawingContext},
dim2::{self, collider::ColliderShape, rigidbody::ApplyAction},
dim2::{self, collider::ColliderShape, joint::JointParams, rigidbody::ApplyAction},
graph::{
physics::{FeatureId, IntegrationParameters, PhysicsPerformanceStatistics},
NodePool,
@@ -209,22 +209,29 @@ fn convert_joint_params(
JointParams::PrismaticJoint(_) => JointAxesMask::LOCKED_PRISMATIC_AXES,
};
let builder = GenericJointBuilder::new(locked_axis)
let mut joint = GenericJointBuilder::new(locked_axis)
.local_frame1(local_frame1)
.local_frame2(local_frame2);
.local_frame2(local_frame2)
.build();
match params {
scene::dim2::joint::JointParams::BallJoint(v) => builder
.limits(
JointAxis::AngX,
[v.limits_angles.start, v.limits_angles.end],
)
.build(),
scene::dim2::joint::JointParams::FixedJoint(_) => builder.build(),
scene::dim2::joint::JointParams::PrismaticJoint(v) => builder
.limits(JointAxis::X, [v.limits.start, v.limits.end])
.build(),
scene::dim2::joint::JointParams::BallJoint(v) => {
if v.limits_enabled {
joint.set_limits(
JointAxis::AngX,
[v.limits_angles.start, v.limits_angles.end],
);
}
}
scene::dim2::joint::JointParams::FixedJoint(_) => {}
scene::dim2::joint::JointParams::PrismaticJoint(v) => {
if v.limits_enabled {
joint.set_limits(JointAxis::X, [v.limits.start, v.limits.end]);
}
}
}
joint
}
// Converts descriptor in a shared shape.
+36 -23
View File
@@ -341,33 +341,46 @@ fn convert_joint_params(
JointParams::RevoluteJoint(_) => JointAxesMask::LOCKED_REVOLUTE_AXES,
};
let builder = GenericJointBuilder::new(locked_axis)
let mut joint = GenericJointBuilder::new(locked_axis)
.local_frame1(local_frame1)
.local_frame2(local_frame2);
.local_frame2(local_frame2)
.build();
match params {
scene::joint::JointParams::BallJoint(v) => builder
.limits(
JointAxis::AngX,
[v.limits_angles.start, v.limits_angles.end],
)
.limits(
JointAxis::AngY,
[v.limits_angles.start, v.limits_angles.end],
)
.limits(
JointAxis::AngZ,
[v.limits_angles.start, v.limits_angles.end],
)
.build(),
scene::joint::JointParams::FixedJoint(_) => builder.build(),
scene::joint::JointParams::PrismaticJoint(v) => builder
.limits(JointAxis::X, [v.limits.start, v.limits.end])
.build(),
scene::joint::JointParams::RevoluteJoint(v) => builder
.limits(JointAxis::AngX, [v.limits.start, v.limits.end])
.build(),
scene::joint::JointParams::BallJoint(v) => {
if v.x_limits_enabled {
joint.set_limits(
JointAxis::AngX,
[v.x_limits_angles.start, v.x_limits_angles.end],
);
}
if v.y_limits_enabled {
joint.set_limits(
JointAxis::AngY,
[v.y_limits_angles.start, v.y_limits_angles.end],
);
}
if v.z_limits_enabled {
joint.set_limits(
JointAxis::AngZ,
[v.z_limits_angles.start, v.z_limits_angles.end],
);
}
}
scene::joint::JointParams::FixedJoint(_) => {}
scene::joint::JointParams::PrismaticJoint(v) => {
if v.limits_enabled {
joint.set_limits(JointAxis::X, [v.limits.start, v.limits.end]);
}
}
scene::joint::JointParams::RevoluteJoint(v) => {
if v.limits_enabled {
joint.set_limits(JointAxis::AngX, [v.limits.start, v.limits.end]);
}
}
}
joint
}
/// Creates new trimesh collider shape from given mesh node. It also bakes scale into
+52 -14
View File
@@ -13,18 +13,16 @@ use crate::{
impl_directly_inheritable_entity_trait,
scene::{
base::{Base, BaseBuilder},
graph::map::NodeHandleMap,
graph::Graph,
graph::{map::NodeHandleMap, Graph},
node::{Node, NodeTrait, SyncContext, TypeUuidProvider},
DirectlyInheritableEntity,
},
utils::log::Log,
};
use rapier3d::dynamics::ImpulseJointHandle;
use std::ops::Range;
use std::{
cell::Cell,
ops::{Deref, DerefMut},
ops::{Deref, DerefMut, Range},
};
/// Ball joint locks any translational moves between two objects on the axis between objects, but
@@ -32,18 +30,46 @@ use std::{
/// pendulum, etc.
#[derive(Clone, Debug, Visit, PartialEq, Inspect)]
pub struct BallJoint {
/// The maximum angle allowed between the two limit axes in world-space.
#[inspect(
description = "The maximum angle allowed between the two limit axes in world-space."
)]
/// Whether X angular limits are enabled or not. Default is `false`
#[inspect(description = "Whether X angular limits are enabled or not.")]
#[visit(optional)] // Backward compatibility
pub limits_angles: Range<f32>,
pub x_limits_enabled: bool,
/// Allowed angle range around local X axis of the joint (in radians).
#[inspect(description = "Allowed angle range around local X axis of the joint (in radians).")]
#[visit(optional)] // Backward compatibility
pub x_limits_angles: Range<f32>,
/// Whether Y angular limits are enabled or not. Default is `false`
#[inspect(description = "Whether Y angular limits are enabled or not.")]
#[visit(optional)] // Backward compatibility
pub y_limits_enabled: bool,
/// Allowed angle range around local Y axis of the joint (in radians).
#[inspect(description = "Allowed angle range around local Y axis of the joint (in radians).")]
#[visit(optional)] // Backward compatibility
pub y_limits_angles: Range<f32>,
/// Whether Z angular limits are enabled or not. Default is `false`
#[inspect(description = "Whether Z angular limits are enabled or not.")]
#[visit(optional)] // Backward compatibility
pub z_limits_enabled: bool,
/// Allowed angle range around local Z axis of the joint (in radians).
#[inspect(description = "Allowed angle range around local Z axis of the joint (in radians).")]
#[visit(optional)] // Backward compatibility
pub z_limits_angles: Range<f32>,
}
impl Default for BallJoint {
fn default() -> Self {
Self {
limits_angles: -std::f32::consts::PI..std::f32::consts::PI,
x_limits_enabled: false,
x_limits_angles: -std::f32::consts::PI..std::f32::consts::PI,
y_limits_enabled: false,
y_limits_angles: -std::f32::consts::PI..std::f32::consts::PI,
z_limits_enabled: false,
z_limits_angles: -std::f32::consts::PI..std::f32::consts::PI,
}
}
}
@@ -57,9 +83,14 @@ pub struct FixedJoint;
/// translations along one axis. The real world example is a sliders that used to support drawers.
#[derive(Clone, Debug, Visit, PartialEq, Inspect)]
pub struct PrismaticJoint {
/// The min an max relative position of the attached bodies along this joint's axis.
/// Whether linear limits along local joint X axis are enabled or not. Default is `false`
#[inspect(description = "Whether linear limits along local joint X axis are enabled or not.")]
#[visit(optional)] // Backward compatibility
pub limits_enabled: bool,
/// The min an max relative position of the attached bodies along local X axis of the joint.
#[inspect(
description = "The min an max relative position of the attached bodies along this joint's axis."
description = "The min an max relative position of the attached bodies along local X axis of the joint."
)]
#[visit(optional)] // Backward compatibility
pub limits: Range<f32>,
@@ -68,6 +99,7 @@ pub struct PrismaticJoint {
impl Default for PrismaticJoint {
fn default() -> Self {
Self {
limits_enabled: false,
limits: -std::f32::consts::PI..std::f32::consts::PI,
}
}
@@ -78,17 +110,23 @@ impl Default for PrismaticJoint {
/// hinge.
#[derive(Clone, Debug, Visit, PartialEq, Inspect)]
pub struct RevoluteJoint {
/// The min and max relative position of the attached bodies along this joint's axis.
/// Whether angular limits around local X axis of the joint are enabled or not. Default is `false`
#[inspect(
description = "The min and max relative position of the attached bodies along this joint's axis."
description = "Whether angular limits around local X axis of the joint are enabled or not."
)]
#[visit(optional)] // Backward compatibility
pub limits_enabled: bool,
/// Allowed angle range around local X axis of the joint (in radians).
#[inspect(description = "Allowed angle range around local X axis of the joint (in radians).")]
#[visit(optional)] // Backward compatibility
pub limits: Range<f32>,
}
impl Default for RevoluteJoint {
fn default() -> Self {
Self {
limits_enabled: false,
limits: -std::f32::consts::PI..std::f32::consts::PI,
}
}