mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
joint limits improvements
- separate limits per axis for ball joint - switch to enable\disable joint limits
This commit is contained in:
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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! {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user