Skip to main content

bevy_rapier2d/reflect/
mod.rs

1use crate::math::Real;
2use bevy::reflect::reflect_remote;
3#[cfg(feature = "fem")]
4use rapier::dynamics::SoftFemParameters;
5use rapier::dynamics::{
6    SoftBodiesSettings, SoftBodyMaterial as RapierSoftBodyMaterial, SoftEdgePlasticFlow,
7    SoftPatchConstraints, SoftRecoverySettings,
8};
9use rapier::{dynamics::IntegrationParameters, prelude::SpringCoefficients};
10
11#[cfg(feature = "dim3")]
12use rapier::dynamics::FrictionModel;
13
14/// Friction models used for all contact constraints between two rigid-bodies.
15///
16/// This selection does not apply to multibodies that always rely on the [`FrictionModel::Coulomb`].
17#[cfg(feature = "dim3")]
18#[reflect_remote(FrictionModel)]
19#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
20#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
21pub enum FrictionModelWrapper {
22    /// A simplified friction model significantly faster to solve than [`Self::Coulomb`]
23    /// but less accurate.
24    ///
25    /// Instead of solving one Coulomb friction constraint per contact in a contact manifold,
26    /// this approximation only solves one Coulomb friction constraint per group of 4 contacts
27    /// in a contact manifold, plus one "twist" constraint. The "twist" constraint is purely
28    /// rotational and aims to eliminate angular movement in the manifold’s tangent plane.
29    #[default]
30    Simplified,
31    /// The coulomb friction model.
32    ///
33    /// This results in one Coulomb friction constraint per contact point.
34    Coulomb,
35}
36
37#[reflect_remote(SpringCoefficients<Real>)]
38#[derive(Copy, Clone, Debug, PartialEq)]
39/// Coefficients for a spring, typically used for configuring constraint softness for contacts and
40/// joints.
41pub struct SpringCoefficientsWrapper {
42    /// Sets the natural frequency (Hz) of the spring-like constraint.
43    ///
44    /// Higher values make the constraint stiffer and resolve constraint violations more quickly.
45    pub natural_frequency: Real,
46    /// Sets the damping ratio for the spring-like constraint.
47    ///
48    /// Larger values make the joint more compliant (allowing more drift before stabilization).
49    pub damping_ratio: Real,
50}
51
52#[reflect_remote(SoftPatchConstraints)]
53#[derive(Copy, Clone, Debug, PartialEq, Eq)]
54#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
55/// What the per-point constraints of the features a soft-body volume constraint acts on do.
56pub enum SoftPatchConstraintsWrapper {
57    /// Keep them as they are (they may fight the volume constraint).
58    Keep,
59    /// Stand them down: the volume constraint alone acts on those features.
60    StandDown,
61    /// Keep them but along the volume constraint's normal, with their separation measured along
62    /// it, so they push the way the constraint does.
63    AlongNormal,
64}
65
66#[reflect_remote(SoftRecoverySettings)]
67#[derive(Copy, Clone, Debug, PartialEq, Default)]
68#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
69/// Runtime configuration of the soft-body tangle detection and recovery stack.
70///
71/// See [`SoftRecoverySettings`] for the details of each field.
72pub struct SoftRecoverySettingsWrapper {
73    /// Raise the speculative contact margin from velocities authored between steps (default:
74    /// `true`).
75    pub authored_velocity_margin: bool,
76    /// Give the edge-vs-edge pass a speculative reach (default: `false`).
77    pub edge_speculation: bool,
78    /// Detect inverted cells each step (default: `true`).
79    pub inverted_cell_detection: bool,
80    /// Detect surface self-crossings each step (default: `true`).
81    pub self_crossing_detection: bool,
82    /// Skip the self-crossing sweep while the surface barely moved (default: `true`).
83    pub detection_motion_gating: bool,
84    /// Detect boundary crossings between pairs of soft surfaces (default: `true`).
85    pub cross_body_detection: bool,
86    /// Self contacts of tangled features stand down (default: `true`).
87    pub self_stand_down: bool,
88    /// A vertex constraint touching a boundary crossing between two surfaces may only expel
89    /// (default: `true`).
90    pub cross_body_expel_gate: bool,
91    /// Edge constraints touching a cross-body boundary crossing stand down (default: `true`).
92    pub edge_stand_down: bool,
93    /// Constraints on crossing-flagged features repel instead of standing down (default:
94    /// `false`).
95    pub crossing_repulsion: bool,
96    /// Guide the crossing repulsion by the pair's volume normal (default: `false`).
97    pub crossing_repulsion_guide: bool,
98    /// Guide the self-crossing repulsion by the fold's volume normal (default: `false`).
99    pub crossing_repulsion_self_guide: bool,
100    /// Material recovery pace, in length units per second (default: `0.5`).
101    pub recovery_pace: Real,
102    /// Intersection-volume contact constraints for closed surfaces (default: `true`).
103    pub overlap_constraints: bool,
104    /// Overlap constraints against rigid colliders too (default: `true`).
105    pub overlap_rigid: bool,
106    /// A self-crossed mesh takes no pair constraint (default: `true`).
107    pub overlap_skip_self_tangled: bool,
108    /// The 3D closed-closed edge constraints stand down on a pair an overlap constraint owns
109    /// (default: `true`).
110    pub overlap_edge_stand_down: bool,
111    /// Bound on the velocity change the coupled constraint may hand any side per step, in
112    /// multiples of the recovery pace (default: `1.0`).
113    pub overlap_constraint_pace: Real,
114    /// What the per-point constraints of the features inside a volume constraint's patch do
115    /// (default: `AlongNormal`).
116    #[reflect(remote = SoftPatchConstraintsWrapper)]
117    pub overlap_patch_constraints: SoftPatchConstraints,
118    /// Measure the intersection volume on the contact skins (default: `false`).
119    pub overlap_skin_volume: bool,
120    /// The skin overlap kept at rest, as a fraction of the pair's skins (default: `0.0`).
121    pub overlap_kept_depth: Real,
122    /// Volume constraints on a body's self-overlaps between distinct surface regions (default:
123    /// `false`).
124    pub overlap_self_regions: bool,
125    /// Push along each constraint's normal instead of the volume gradients (default: `true`).
126    pub overlap_normal_push: bool,
127    /// Split each pair's patch into a grid of cells with their own constraint (default:
128    /// `false`).
129    pub overlap_multi_volume: bool,
130    /// Cells per tangent axis of the multi-volume grid (default: `3`).
131    pub overlap_split: u32,
132    /// Steps without progress of a pair's volume estimate before its positional correction
133    /// stands down (default: `240`).
134    pub overlap_patience: u32,
135    /// Relative drop of the estimate that counts as progress for the patience (default:
136    /// `0.02`).
137    pub overlap_progress_margin: Real,
138}
139
140#[cfg(feature = "fem")]
141#[reflect_remote(SoftFemParameters)]
142#[derive(Copy, Clone, Debug, PartialEq, Default)]
143#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
144/// Tuning of the FEM soft-body solver.
145pub struct SoftFemParametersWrapper {
146    /// Relative residual at which the conjugate gradient stops (default: `1.0e-5`).
147    pub linear_tolerance: Real,
148    /// Hard cap on the conjugate-gradient iterations (default: `20`).
149    pub max_linear_iterations: usize,
150    /// Largest number of degrees of freedom for which the step-start matrix of a body is
151    /// factorized directly (default: `600`).
152    pub max_dense_dofs: usize,
153}
154
155// Duplicated because `reflect_remote` doesn't support conditional fields.
156#[cfg(not(feature = "fem"))]
157#[reflect_remote(SoftBodiesSettings)]
158#[derive(Copy, Clone, Debug, PartialEq, Default)]
159#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
160/// Simulation settings shared by every soft body of a Rapier context.
161pub struct SoftBodiesSettingsWrapper {
162    /// Runtime toggles and tuning for the soft-body tangle detection and recovery stack.
163    #[reflect(remote = SoftRecoverySettingsWrapper)]
164    pub recovery: SoftRecoverySettings,
165    /// Strain beyond which a soft-body constraint is re-solved after the contacts inside every
166    /// substep (default: `0.75`).
167    pub resweep_strain: Real,
168    /// Maximum number of extra substeps a soft body requests for its island while it is hit fast
169    /// (default: `4`).
170    pub max_extra_substeps: usize,
171    /// Factor applied to the contact softness natural frequencies for the soft-body contacts
172    /// (default: `4.0`).
173    pub contact_stiffening: Real,
174}
175
176#[cfg(feature = "fem")]
177#[reflect_remote(SoftBodiesSettings)]
178#[derive(Copy, Clone, Debug, PartialEq, Default)]
179#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
180/// Simulation settings shared by every soft body of a Rapier context.
181pub struct SoftBodiesSettingsWrapper {
182    /// Runtime toggles and tuning for the soft-body tangle detection and recovery stack.
183    #[reflect(remote = SoftRecoverySettingsWrapper)]
184    pub recovery: SoftRecoverySettings,
185    /// Strain beyond which a soft-body constraint is re-solved after the contacts inside every
186    /// substep (default: `0.75`).
187    pub resweep_strain: Real,
188    /// Maximum number of extra substeps a soft body requests for its island while it is hit fast
189    /// (default: `4`).
190    pub max_extra_substeps: usize,
191    /// Factor applied to the contact softness natural frequencies for the soft-body contacts
192    /// (default: `4.0`).
193    pub contact_stiffening: Real,
194    /// Tuning of the FEM soft-body solver.
195    #[reflect(remote = SoftFemParametersWrapper)]
196    pub fem: SoftFemParameters,
197}
198
199#[reflect_remote(SoftEdgePlasticFlow)]
200#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
201/// Which strains make a soft-body edge flow plastically.
202pub enum SoftEdgePlasticFlowWrapper {
203    /// Both a squeeze and a stretch past the yield take a permanent set.
204    #[default]
205    Both,
206    /// Only a squeeze sets.
207    Compression,
208    /// Only a stretch sets.
209    Tension,
210}
211
212#[reflect_remote(RapierSoftBodyMaterial)]
213#[derive(Copy, Clone, Debug, PartialEq, Default)]
214/// The stiffness, damping, plasticity and tearing parameters of a soft body.
215///
216/// See [`RapierSoftBodyMaterial`] for the details of each field.
217pub struct SoftBodyMaterialWrapper {
218    /// Softness of the structural edges.
219    #[reflect(remote = SpringCoefficientsWrapper)]
220    pub edge_softness: SpringCoefficients<Real>,
221    /// Softness of the bending edges and dihedral constraints.
222    #[reflect(remote = SpringCoefficientsWrapper)]
223    pub bend_softness: SpringCoefficients<Real>,
224    /// Softness of the per-cell volume constraints and of the global volume preservation.
225    #[reflect(remote = SpringCoefficientsWrapper)]
226    pub volume_softness: SpringCoefficients<Real>,
227    /// Softness of the shape-matching constraints.
228    #[reflect(remote = SpringCoefficientsWrapper)]
229    pub shape_matching_softness: SpringCoefficients<Real>,
230    /// Young's modulus of the elastic cells.
231    pub young_modulus: Real,
232    /// Poisson's ratio of the elastic cells, in `[0, 0.5)`.
233    pub poisson_ratio: Real,
234    /// Damping ratio of the elastic cells.
235    pub elastic_damping_ratio: Real,
236    /// Plastic yield of the elastic cells (`0.0`: no plasticity).
237    pub plastic_yield: Real,
238    /// Rate (per second) at which the strain in excess of the yield is absorbed into the rest
239    /// shape.
240    pub plastic_creep: Real,
241    /// Largest accumulated plastic deformation of a cell.
242    pub plastic_max: Real,
243    /// Rate (per second) at which the particles' velocities are pulled toward the body's best-fit
244    /// rigid motion.
245    pub deformation_damping: Real,
246    /// Plastic yield of the edges (`0.0`: none).
247    pub edge_plastic_yield: Real,
248    /// Rate (per second) at which an edge's strain in excess of its yield is absorbed into its
249    /// rest length.
250    pub edge_plastic_creep: Real,
251    /// Largest permanent set an edge may accumulate, as a fraction of its initial length.
252    pub edge_plastic_max: Real,
253    /// Whether the edges take a permanent set under a squeeze, a stretch, or both.
254    #[reflect(remote = SoftEdgePlasticFlowWrapper)]
255    pub edge_plastic_flow: SoftEdgePlasticFlow,
256    /// Strain beyond which elements break (`None`: unbreakable).
257    pub tear_strain: Option<Real>,
258    /// Force beyond which the edges break (`None`: unbreakable).
259    pub tear_force: Option<Real>,
260    /// Time constant, in seconds, over which an element's load is smoothed before the tear test.
261    pub tear_smoothing: Real,
262    /// How much tougher an undamaged interior element is than a surface one.
263    pub interior_strength: Real,
264    /// Maximum number of edges torn per step.
265    pub max_tears_per_step: u32,
266    /// The smallest piece, in measure elements, a tear may split off.
267    pub min_piece: Option<u32>,
268}
269
270#[cfg(not(feature = "dim3"))]
271#[reflect_remote(IntegrationParameters)]
272#[derive(Copy, Clone, Debug, PartialEq)]
273/// Parameters for a time-step of the physics engine.
274pub struct IntegrationParametersWrapper {
275    /// The timestep length (default: `1.0 / 60.0`).
276    pub dt: Real,
277    /// Minimum timestep size when using CCD with multiple substeps (default: `1.0 / 60.0 / 100.0`).
278    ///
279    /// When CCD with multiple substeps is enabled, the timestep is subdivided
280    /// into smaller pieces. This timestep subdivision won't generate timestep
281    /// lengths smaller than `min_ccd_dt`.
282    ///
283    /// Setting this to a large value will reduce the opportunity to performing
284    /// CCD substepping, resulting in potentially more time dropped by the
285    /// motion-clamping mechanism. Setting this to an very small value may lead
286    /// to numerical instabilities.
287    pub min_ccd_dt: Real,
288
289    /// Softness coefficients for contact constraints.
290    #[reflect(remote = SpringCoefficientsWrapper)]
291    pub contact_softness: SpringCoefficients<Real>,
292
293    /// Softness coefficients for contact constraints where one side is a fixed body.
294    ///
295    /// Stiffer than [`IntegrationParameters::contact_softness`] by default so bodies are
296    /// held firmly against static walls/floors; set equal to
297    /// [`IntegrationParameters::contact_softness`] to disable.
298    #[reflect(remote = SpringCoefficientsWrapper)]
299    pub static_contact_softness: SpringCoefficients<Real>,
300
301    /// The coefficient in `[0, 1]` applied to warmstart impulses, i.e., impulses that are used as the
302    /// initial solution (instead of 0) at the next simulation step.
303    ///
304    /// This should generally be set to 1.
305    ///
306    /// (default `1.0`).
307    pub warmstart_coefficient: Real,
308
309    /// The approximate size of most dynamic objects in the scene.
310    ///
311    /// This value is used internally to estimate some length-based tolerance. In particular, the
312    /// values [`IntegrationParameters::allowed_linear_error`],
313    /// [`IntegrationParameters::max_corrective_velocity`],
314    /// [`IntegrationParameters::prediction_distance`], [`RigidBodyActivation::normalized_linear_threshold`]
315    /// are scaled by this value implicitly.
316    ///
317    /// This value can be understood as the number of units-per-meter in your physical world compared
318    /// to a human-sized world in meter. For example, in a 2d game, if your typical object size is 100
319    /// pixels, set the [`Self::length_unit`] parameter to 100.0. The physics engine will interpret
320    /// it as if 100 pixels is equivalent to 1 meter in its various internal threshold.
321    /// (default `1.0`).
322    pub length_unit: Real,
323
324    /// Amount of penetration the engine won’t attempt to correct (default: `0.001m`).
325    ///
326    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
327    pub normalized_allowed_linear_error: Real,
328    /// Maximum amount of penetration the solver will attempt to resolve in one timestep (default: `10.0`).
329    ///
330    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
331    pub normalized_max_corrective_velocity: Real,
332    /// The maximal distance separating two objects that will generate predictive contacts (default: `0.002m`).
333    ///
334    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
335    pub normalized_prediction_distance: Real,
336    /// Maximum linear velocity a body may have after each solver substep (default: `400.0` m/s).
337    ///
338    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
339    pub normalized_max_linear_velocity: Real,
340    /// The number of solver iterations run by the constraints solver for calculating forces (default: `4`).
341    pub num_solver_iterations: usize,
342    /// Number of internal Project Gauss Seidel (PGS) iterations run at each solver iteration (default: `1`).
343    pub num_internal_pgs_iterations: usize,
344    /// The number of stabilization iterations run at each solver iterations (default: `1`).
345    pub num_internal_stabilization_iterations: usize,
346    /// Maximum number of substeps performed by the  solver (default: `1`).
347    pub max_ccd_substeps: usize,
348    /// If enabled, contact manifolds of a collider pair sharing (nearly) the same normal are
349    /// merged into one "cluster" manifold before constraint generation (default: `true`, 3D only).
350    pub contact_clustering: bool,
351    /// If enabled, a contact pair that barely moved since its last full narrow-phase update
352    /// skips contact determination and keeps its existing contact points (default: `true`).
353    pub contact_recycling: bool,
354    /// Maximum relative-pose drift below which a contact pair may be recycled instead of fully
355    /// updated (default: `0.05`). Only used when contact recycling is enabled.
356    ///
357    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
358    pub normalized_contact_recycle_distance: Real,
359    /// If `false`, friction is only solved during the unbiased (relax) pass of each substep
360    /// instead of both passes (default: `false`).
361    pub friction_in_bias_pass: bool,
362    /// If enabled, impulse-joint constraints are warm-started like contacts (default: `false`).
363    pub warmstart_joints: bool,
364    /// Simulation settings shared by every soft body.
365    #[reflect(remote = SoftBodiesSettingsWrapper)]
366    pub soft_bodies: rapier::dynamics::SoftBodiesSettings,
367}
368
369// These structs are duplicated in their entirety due to [`FrictionModel`] not being available in 2D, and `bevy::reflect_remote` not supporting conditional fields.
370#[cfg(feature = "dim3")]
371#[reflect_remote(IntegrationParameters)]
372#[derive(Copy, Clone, Debug, PartialEq)]
373/// Parameters for a time-step of the physics engine.
374pub struct IntegrationParametersWrapper {
375    /// The timestep length (default: `1.0 / 60.0`).
376    pub dt: Real,
377    /// Minimum timestep size when using CCD with multiple substeps (default: `1.0 / 60.0 / 100.0`).
378    ///
379    /// When CCD with multiple substeps is enabled, the timestep is subdivided
380    /// into smaller pieces. This timestep subdivision won't generate timestep
381    /// lengths smaller than `min_ccd_dt`.
382    ///
383    /// Setting this to a large value will reduce the opportunity to performing
384    /// CCD substepping, resulting in potentially more time dropped by the
385    /// motion-clamping mechanism. Setting this to an very small value may lead
386    /// to numerical instabilities.
387    pub min_ccd_dt: Real,
388
389    /// Softness coefficients for contact constraints.
390    #[reflect(remote = SpringCoefficientsWrapper)]
391    pub contact_softness: SpringCoefficients<Real>,
392
393    /// Softness coefficients for contact constraints where one side is a fixed body.
394    ///
395    /// Stiffer than [`IntegrationParameters::contact_softness`] by default so bodies are
396    /// held firmly against static walls/floors; set equal to
397    /// [`IntegrationParameters::contact_softness`] to disable.
398    #[reflect(remote = SpringCoefficientsWrapper)]
399    pub static_contact_softness: SpringCoefficients<Real>,
400
401    /// The coefficient in `[0, 1]` applied to warmstart impulses, i.e., impulses that are used as the
402    /// initial solution (instead of 0) at the next simulation step.
403    ///
404    /// This should generally be set to 1.
405    ///
406    /// (default `1.0`).
407    pub warmstart_coefficient: Real,
408
409    /// The approximate size of most dynamic objects in the scene.
410    ///
411    /// This value is used internally to estimate some length-based tolerance. In particular, the
412    /// values [`IntegrationParameters::allowed_linear_error`],
413    /// [`IntegrationParameters::max_corrective_velocity`],
414    /// [`IntegrationParameters::prediction_distance`], [`RigidBodyActivation::normalized_linear_threshold`]
415    /// are scaled by this value implicitly.
416    ///
417    /// This value can be understood as the number of units-per-meter in your physical world compared
418    /// to a human-sized world in meter. For example, in a 2d game, if your typical object size is 100
419    /// pixels, set the [`Self::length_unit`] parameter to 100.0. The physics engine will interpret
420    /// it as if 100 pixels is equivalent to 1 meter in its various internal threshold.
421    /// (default `1.0`).
422    pub length_unit: Real,
423
424    /// Amount of penetration the engine won’t attempt to correct (default: `0.001m`).
425    ///
426    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
427    pub normalized_allowed_linear_error: Real,
428    /// Maximum amount of penetration the solver will attempt to resolve in one timestep (default: `10.0`).
429    ///
430    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
431    pub normalized_max_corrective_velocity: Real,
432    /// The maximal distance separating two objects that will generate predictive contacts (default: `0.002m`).
433    ///
434    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
435    pub normalized_prediction_distance: Real,
436    /// Maximum linear velocity a body may have after each solver substep (default: `400.0` m/s).
437    ///
438    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
439    pub normalized_max_linear_velocity: Real,
440    /// The number of solver iterations run by the constraints solver for calculating forces (default: `4`).
441    pub num_solver_iterations: usize,
442    /// Number of internal Project Gauss Seidel (PGS) iterations run at each solver iteration (default: `1`).
443    pub num_internal_pgs_iterations: usize,
444    /// The number of stabilization iterations run at each solver iterations (default: `1`).
445    pub num_internal_stabilization_iterations: usize,
446    /// Maximum number of substeps performed by the  solver (default: `1`).
447    pub max_ccd_substeps: usize,
448    /// If enabled, contact manifolds of a collider pair sharing (nearly) the same normal are
449    /// merged into one "cluster" manifold before constraint generation (default: `true`, 3D only).
450    pub contact_clustering: bool,
451    /// If enabled, a contact pair that barely moved since its last full narrow-phase update
452    /// skips contact determination and keeps its existing contact points (default: `true`).
453    pub contact_recycling: bool,
454    /// Maximum relative-pose drift below which a contact pair may be recycled instead of fully
455    /// updated (default: `0.05`). Only used when contact recycling is enabled.
456    ///
457    /// This value is implicitly scaled by [`IntegrationParameters::length_unit`].
458    pub normalized_contact_recycle_distance: Real,
459    /// If `false`, friction is only solved during the unbiased (relax) pass of each substep
460    /// instead of both passes (default: `false`).
461    pub friction_in_bias_pass: bool,
462    /// If enabled, impulse-joint constraints are warm-started like contacts (default: `false`).
463    pub warmstart_joints: bool,
464    /// Simulation settings shared by every soft body.
465    #[reflect(remote = SoftBodiesSettingsWrapper)]
466    pub soft_bodies: rapier::dynamics::SoftBodiesSettings,
467    /// Friction models used for all contact constraints between two rigid-bodies.
468    #[reflect(remote = FrictionModelWrapper)]
469    pub friction_model: FrictionModel,
470}
471
472#[cfg(feature = "dim2")]
473#[reflect_remote(rapier::dynamics::JointAxis)]
474#[derive(Copy, Clone, Debug, PartialEq)]
475/// Identifiers of degrees of freedoms of a joint.
476pub enum JointAxisWrapper {
477    /// The linear (translational) degree of freedom along the joint’s local X axis.
478    LinX = 0,
479    /// The linear (translational) degree of freedom along the joint’s local Y axis.
480    LinY,
481    /// The rotational degree of freedom of the joint.
482    AngX,
483}
484
485#[cfg(feature = "dim3")]
486#[reflect_remote(rapier::dynamics::JointAxis)]
487#[derive(Copy, Clone, Debug, PartialEq)]
488/// Identifiers of degrees of freedoms of a joint.
489pub enum JointAxisWrapper {
490    /// The linear (translational) degree of freedom along the joint’s local X axis.
491    LinX = 0,
492    /// The linear (translational) degree of freedom along the joint’s local Y axis.
493    LinY,
494    /// The linear (translational) degree of freedom along the joint’s local Z axis.
495    LinZ,
496    /// The rotational degree of freedom along the joint’s local X axis.
497    AngX,
498    /// The rotational degree of freedom along the joint’s local Y axis.
499    AngY,
500    /// The rotational degree of freedom along the joint’s local Z axis.
501    AngZ,
502}
503
504#[cfg(feature = "dim3")]
505#[reflect_remote(rapier::control::WheelTuning)]
506#[derive(Copy, Clone, Debug, PartialEq)]
507/// Parameters affecting the physical behavior of a wheel of a ray-cast vehicle.
508pub struct WheelTuningWrapper {
509    /// The suspension stiffness.
510    ///
511    /// Increase this value if the suspension appears to not push the vehicle strong enough.
512    pub suspension_stiffness: Real,
513    /// The suspension’s damping when it is being compressed.
514    pub suspension_compression: Real,
515    /// The suspension’s damping when it is being released.
516    ///
517    /// Increase this value if the suspension appears to overshoot.
518    pub suspension_damping: Real,
519    /// The maximum distance the suspension can travel before and after its resting length.
520    pub max_suspension_travel: Real,
521    /// The multiplier of friction between a tire and the collider it's on top of.
522    pub side_friction_stiffness: Real,
523    /// Parameter controlling how much traction the tire has.
524    ///
525    /// The larger the value, the more instantaneous braking will happen (with the risk of
526    /// causing the vehicle to flip if it’s too strong).
527    pub friction_slip: Real,
528    /// The maximum force applied by the suspension.
529    pub max_suspension_force: Real,
530}
531
532#[cfg(any(feature = "debug-render-3d", feature = "debug-render-2d"))]
533#[reflect_remote(rapier::pipeline::DebugRenderStyle)]
534#[derive(Copy, Clone, Debug, PartialEq)]
535/// Style used for computing colors when rendering the scene with the debug-renderer.
536///
537/// Colors are in HSLA format: `[hue 0..=360, saturation 0..=1, lightness 0..=1, alpha 0..=1]`.
538pub struct DebugRenderStyleWrapper {
539    /// The number of subdivisions used to approximate the curved parts of a shape with smooth
540    /// faces.
541    pub subdivisions: u32,
542    /// The number of subdivisions used to approximate the curved borders of round shapes.
543    pub border_subdivisions: u32,
544    /// The color of colliders attached to dynamic rigid-bodies.
545    pub collider_dynamic_color: [f32; 4],
546    /// The color of colliders attached to fixed rigid-bodies.
547    pub collider_fixed_color: [f32; 4],
548    /// The color of colliders attached to kinematic rigid-bodies.
549    pub collider_kinematic_color: [f32; 4],
550    /// The color of colliders not attached to any rigid-body.
551    pub collider_parentless_color: [f32; 4],
552    /// The color of the line between a rigid-body’s center-of-mass and the anchors of its
553    /// attached impulse joints.
554    pub impulse_joint_anchor_color: [f32; 4],
555    /// The color of the line between the two anchors of an impulse joint.
556    pub impulse_joint_separation_color: [f32; 4],
557    /// The color of the line between a rigid-body’s center-of-mass and the anchors of its
558    /// attached multibody joints.
559    pub multibody_joint_anchor_color: [f32; 4],
560    /// The color of the line between the two anchors of a multibody joint.
561    pub multibody_joint_separation_color: [f32; 4],
562    /// Color multiplier applied to the objects attached to sleeping rigid-bodies.
563    pub sleep_color_multiplier: [f32; 4],
564    /// Color multiplier applied to the objects attached to awake rigid-bodies eligible for sleep.
565    pub sleep_eligible_color_multiplier: [f32; 4],
566    /// Color multiplier applied to the objects attached to disabled rigid-bodies.
567    pub disabled_color_multiplier: [f32; 4],
568    /// The length of the local coordinate axes rendered for a rigid-body.
569    pub rigid_body_axes_length: Real,
570    /// The color for the segments joining the two contact points.
571    pub contact_depth_color: [f32; 4],
572    /// The color of the contact normals.
573    pub contact_normal_color: [f32; 4],
574    /// The length of the contact normals.
575    pub contact_normal_length: Real,
576    /// The color of the soft bodies' elements.
577    pub soft_body_element_color: [f32; 4],
578    /// The color of an unloaded soft-body element when coloring the elements by their load.
579    pub soft_body_slack_color: [f32; 4],
580    /// The color of a soft-body element at its tear threshold when coloring the elements by
581    /// their load.
582    pub soft_body_loaded_color: [f32; 4],
583    /// Color of the soft-body cluster frames.
584    pub soft_body_frame_color: [f32; 4],
585    /// The color of the colliders' AABBs.
586    pub collider_aabb_color: [f32; 4],
587    /// The color of the vertex pseudo-normals of triangle-meshes and polylines.
588    pub vertex_pseudo_normal_color: [f32; 4],
589    /// The color of the edge pseudo-normals of triangle-meshes (3D only).
590    pub edge_pseudo_normal_color: [f32; 4],
591    /// The length of the pseudo-normals.
592    pub pseudo_normal_length: Real,
593    /// Color of the soft bodies' volume constraints' normals.
594    pub volume_contact_normal_color: [f32; 4],
595    /// Color of the volume gradients drawn at the particles of a volume constraint.
596    pub volume_gradient_color: [f32; 4],
597}