diff --git a/CHANGELOG.md b/CHANGELOG.md index bcb32e91..eba5e2d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +### 0.19.0 (05 Sept. 2025) + +### Modified + +- Update to Rapier 0.29.0 which includes performance improvements for scenes involving a lot of contact constraints. + See https://github.com/dimforge/rapier/pull/876 for details. +- Renamed the `RigidBody.invPrincipalInertiaSqrt` and `.effectiveWorldInvInertiaSqrt` methods to + `RigidBody.invPrincipalInertia` and `.effectiveWorldInvInertia` (removed the `Sqrt` suffix). These methods will now + return the actual inverse angular inertia matrix rather than its square root. +- Removed methods related to the legacy PGS solver: `World.numAdditionalFrictionIterations`, + `switchToStandardPgsSolver`, `switchToSmallStepsPgsSolver`, `switchToSmallStepsPgsSolverWithoutWarmstart`. + ### 0.18.2 (13 August 2025) ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 703f4f98..b3a72621 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -338,7 +338,7 @@ dependencies = [ [[package]] name = "dimforge_rapier2d" -version = "0.18.1" +version = "0.19.0" dependencies = [ "bincode", "js-sys", @@ -352,7 +352,7 @@ dependencies = [ [[package]] name = "dimforge_rapier2d-deterministic" -version = "0.18.1" +version = "0.19.0" dependencies = [ "bincode", "js-sys", @@ -366,7 +366,7 @@ dependencies = [ [[package]] name = "dimforge_rapier2d-simd" -version = "0.18.1" +version = "0.19.0" dependencies = [ "bincode", "js-sys", @@ -380,7 +380,7 @@ dependencies = [ [[package]] name = "dimforge_rapier3d" -version = "0.18.1" +version = "0.19.0" dependencies = [ "bincode", "js-sys", @@ -394,7 +394,7 @@ dependencies = [ [[package]] name = "dimforge_rapier3d-deterministic" -version = "0.18.1" +version = "0.19.0" dependencies = [ "bincode", "js-sys", @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "dimforge_rapier3d-simd" -version = "0.18.1" +version = "0.19.0" dependencies = [ "bincode", "js-sys", @@ -459,6 +459,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "generic-array" version = "0.14.7" @@ -617,7 +623,16 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "foldhash 0.2.0", "serde", ] @@ -693,7 +708,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.5", "serde", ] @@ -911,9 +926,9 @@ dependencies = [ [[package]] name = "parry2d" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3c2b76147dc43564857a6e31e112f4c6b947ad63398f38a4d6a1a734b9893a1" +checksum = "8240961674a91f3eb4af1bb7451f27c18a07813d223af73789bd90b296f69940" dependencies = [ "approx", "arrayvec", @@ -921,7 +936,8 @@ dependencies = [ "downcast-rs", "either", "ena", - "hashbrown", + "foldhash 0.2.0", + "hashbrown 0.16.0", "indexmap", "log", "nalgebra", @@ -938,9 +954,9 @@ dependencies = [ [[package]] name = "parry3d" -version = "0.23.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ef9c6706eddddd1e5d60a4742e66734d4984045cc3cc3ad29caff835306b9b1" +checksum = "29a58098398ec9b65abcd8c04501430bd273e3bb48ef3664d4d4e0eb7a44029d" dependencies = [ "approx", "arrayvec", @@ -948,8 +964,9 @@ dependencies = [ "downcast-rs", "either", "ena", + "foldhash 0.2.0", "glam 0.30.5", - "hashbrown", + "hashbrown 0.16.0", "indexmap", "log", "nalgebra", @@ -1170,9 +1187,9 @@ dependencies = [ [[package]] name = "rapier2d" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e4cb5dcf7ddba34b02408fde796237d4349e6b2ef5df7cc7efdfa85bf7c7fbe" +checksum = "49586478ee35cd09ca37c7c2eaeb2b4e01ffee038163cd4c45005dbb8046261d" dependencies = [ "approx", "arrayvec", @@ -1189,16 +1206,18 @@ dependencies = [ "rustc-hash", "serde", "simba", + "static_assertions", "thiserror", "vec_map", "web-time", + "wide", ] [[package]] name = "rapier3d" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b32e9e278b6a9b6a692e061c29031f6a4cc448843e9f150f4e02b3e86edc229" +checksum = "30921dd14f66b5b9fd6e904ce66229640e31241f1fa4e760c2ce4a2ce8ed4dc6" dependencies = [ "approx", "arrayvec", @@ -1215,9 +1234,11 @@ dependencies = [ "rustc-hash", "serde", "simba", + "static_assertions", "thiserror", "vec_map", "web-time", + "wide", ] [[package]] @@ -1379,9 +1400,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "simba" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" +checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" dependencies = [ "approx", "libm", @@ -1425,7 +1446,7 @@ version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a14e31a007e9f85c32784b04f89e6e194bb252a4d41b4a8ccd9e77245d901c8c" dependencies = [ - "hashbrown", + "hashbrown 0.15.5", "num-traits", "robust", "serde", @@ -1676,8 +1697,6 @@ dependencies = [ [[package]] name = "wide" version = "0.7.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" dependencies = [ "bytemuck", "safe_arch", diff --git a/builds/prepare_builds/templates/Cargo.toml.tera b/builds/prepare_builds/templates/Cargo.toml.tera index 68667d72..7a01f1b5 100644 --- a/builds/prepare_builds/templates/Cargo.toml.tera +++ b/builds/prepare_builds/templates/Cargo.toml.tera @@ -1,6 +1,6 @@ [package] name = "dimforge_{{ js_package_name }}" # Can't be named rapier{{ dimension }}d which conflicts with the dependency. -version = "0.18.2" +version = "0.19.0" authors = ["Sébastien Crozet "] description = "{{ dimension }}-dimensional physics engine in Rust - official JS bindings." documentation = "https://rapier.rs/rustdoc/rapier{{ dimension }}d/index.html" @@ -27,7 +27,7 @@ rust.unexpected_cfgs = { level = "warn", check-cfg = [ ] } [dependencies] -rapier{{ dimension }}d = { version = "0.28.0", features = [ +rapier{{ dimension }}d = { version = "0.29.0", features = [ "serde-serialize", "debug-render", "profiler", diff --git a/src.ts/dynamics/integration_parameters.ts b/src.ts/dynamics/integration_parameters.ts index 806d257d..b7253e21 100644 --- a/src.ts/dynamics/integration_parameters.ts +++ b/src.ts/dynamics/integration_parameters.ts @@ -61,13 +61,6 @@ export class IntegrationParameters { return this.raw.numSolverIterations; } - /** - * Number of addition friction resolution iteration run during the last solver sub-step (default: `4`). - */ - get numAdditionalFrictionIterations(): number { - return this.raw.numAdditionalFrictionIterations; - } - /** * Number of internal Project Gauss Seidel (PGS) iterations run at each solver iteration (default: `1`). */ @@ -116,13 +109,6 @@ export class IntegrationParameters { this.raw.numSolverIterations = value; } - /** - * Sets the number of addition friction resolution iteration run during the last solver sub-step (default: `4`). - */ - set numAdditionalFrictionIterations(value: number) { - this.raw.numAdditionalFrictionIterations = value; - } - /** * Sets the number of internal Project Gauss Seidel (PGS) iterations run at each solver iteration (default: `1`). */ @@ -137,16 +123,4 @@ export class IntegrationParameters { set maxCcdSubsteps(value: number) { this.raw.maxCcdSubsteps = value; } - - public switchToStandardPgsSolver() { - this.raw.switchToStandardPgsSolver(); - } - - public switchToSmallStepsPgsSolver() { - this.raw.switchToSmallStepsPgsSolver(); - } - - public switchToSmallStepsPgsSolverWithoutWarmstart() { - this.raw.switchToSmallStepsPgsSolverWithoutWarmstart(); - } } diff --git a/src.ts/dynamics/rigid_body.ts b/src.ts/dynamics/rigid_body.ts index 646223b6..8f52dbe5 100644 --- a/src.ts/dynamics/rigid_body.ts +++ b/src.ts/dynamics/rigid_body.ts @@ -582,8 +582,8 @@ export class RigidBody { * * Components set to zero are assumed to be infinite along the corresponding principal axis. */ - public invPrincipalInertiaSqrt(): number { - return this.rawSet.rbInvPrincipalInertiaSqrt(this.handle); + public invPrincipalInertia(): number { + return this.rawSet.rbInvPrincipalInertia(this.handle); } // #endif @@ -594,9 +594,9 @@ export class RigidBody { * * Components set to zero are assumed to be infinite along the corresponding principal axis. */ - public invPrincipalInertiaSqrt(): Vector { + public invPrincipalInertia(): Vector { return VectorOps.fromRaw( - this.rawSet.rbInvPrincipalInertiaSqrt(this.handle), + this.rawSet.rbInvPrincipalInertia(this.handle), ); } @@ -636,23 +636,23 @@ export class RigidBody { // #if DIM2 /** - * The square-root of the world-space inverse angular inertia tensor of the rigid-body, + * The world-space inverse angular inertia tensor of the rigid-body, * taking into account rotation locking. */ - public effectiveWorldInvInertiaSqrt(): number { - return this.rawSet.rbEffectiveWorldInvInertiaSqrt(this.handle); + public effectiveWorldInvInertia(): number { + return this.rawSet.rbEffectiveWorldInvInertia(this.handle); } // #endif // #if DIM3 /** - * The square-root of the world-space inverse angular inertia tensor of the rigid-body, + * The world-space inverse angular inertia tensor of the rigid-body, * taking into account rotation locking. */ - public effectiveWorldInvInertiaSqrt(): SdpMatrix3 { + public effectiveWorldInvInertia(): SdpMatrix3 { return SdpMatrix3Ops.fromRaw( - this.rawSet.rbEffectiveWorldInvInertiaSqrt(this.handle), + this.rawSet.rbEffectiveWorldInvInertia(this.handle), ); } diff --git a/src.ts/pipeline/world.ts b/src.ts/pipeline/world.ts index b8f7b030..9ee85616 100644 --- a/src.ts/pipeline/world.ts +++ b/src.ts/pipeline/world.ts @@ -376,25 +376,6 @@ export class World { this.integrationParameters.numSolverIterations = niter; } - /** - * Number of addition friction resolution iteration run during the last solver sub-step (default: `4`). - */ - get numAdditionalFrictionIterations(): number { - return this.integrationParameters.numAdditionalFrictionIterations; - } - - /** - * Sets the number of addition friction resolution iteration run during the last solver sub-step (default: `4`). - * - * The greater this value is, the most realistic friction will be. - * However a greater number of iterations is more computationally intensive. - * - * @param niter - The new number of additional friction iterations. - */ - set numAdditionalFrictionIterations(niter: number) { - this.integrationParameters.numAdditionalFrictionIterations = niter; - } - /** * Number of internal Project Gauss Seidel (PGS) iterations run at each solver iteration (default: `1`). */ @@ -435,47 +416,6 @@ export class World { this.integrationParameters.maxCcdSubsteps = substeps; } - /// Configures the integration parameters to match the old PGS solver - /// from Rapier JS version <= 0.11. - /// - /// This solver was slightly faster than the new one but resulted - /// in less stable joints and worse convergence rates. - /// - /// This should only be used for comparison purpose or if you are - /// experiencing problems with the new solver. - /// - /// NOTE: this does not affect any `RigidBody.additional_solver_iterations` that will - /// still create solver iterations based on the new "small-steps" PGS solver. - public switchToStandardPgsSolver() { - this.integrationParameters.switchToStandardPgsSolver(); - } - - /// Configures the integration parameters to match the new "small-steps" PGS solver - /// from Rapier version >= 0.12. - /// - /// The "small-steps" PGS solver is the default one when creating the physics world. So - /// calling this function is generally not needed unless `World.switch_to_standard_pgs_solver` - /// was called. - /// - /// This solver results in more stable joints and significantly better convergence - /// rates but is slightly slower in its default settings. - public switchToSmallStepsPgsSolver() { - this.integrationParameters.switchToSmallStepsPgsSolver(); - } - - /// Configures the integration parameters to match the new "small-steps" PGS solver - /// from Rapier version >= 0.12. Warmstarting is disabled. - /// - /// The "small-steps" PGS solver is the default one when creating the physics world. So - /// calling this function is generally not needed unless `World.switch_to_standard_pgs_solver` - /// was called. - /// - /// This solver results in more stable joints and significantly better convergence - /// rates but is slightly slower in its default settings. - public switchToSmallStepsPgsSolverWithoutWarmstart() { - this.integrationParameters.switchToSmallStepsPgsSolverWithoutWarmstart(); - } - /** * Creates a new rigid-body from the given rigid-body descriptor. * diff --git a/src/dynamics/integration_parameters.rs b/src/dynamics/integration_parameters.rs index 3416c4d5..b273e057 100644 --- a/src/dynamics/integration_parameters.rs +++ b/src/dynamics/integration_parameters.rs @@ -1,5 +1,4 @@ use rapier::dynamics::IntegrationParameters; -use std::num::NonZeroUsize; use wasm_bindgen::prelude::*; #[wasm_bindgen] @@ -34,12 +33,7 @@ impl RawIntegrationParameters { #[wasm_bindgen(getter)] pub fn numSolverIterations(&self) -> usize { - self.0.num_solver_iterations.get() - } - - #[wasm_bindgen(getter)] - pub fn numAdditionalFrictionIterations(&self) -> usize { - self.0.num_additional_friction_iterations + self.0.num_solver_iterations } #[wasm_bindgen(getter)] @@ -84,15 +78,11 @@ impl RawIntegrationParameters { #[wasm_bindgen(setter)] pub fn set_numSolverIterations(&mut self, value: usize) { - self.0.num_solver_iterations = NonZeroUsize::new(value.max(1)).unwrap() - } - #[wasm_bindgen(setter)] - pub fn set_numAdditionalFrictionIterations(&mut self, value: usize) { - self.0.num_additional_friction_iterations = value + self.0.num_solver_iterations = value; } #[wasm_bindgen(setter)] pub fn set_numInternalPgsIterations(&mut self, value: usize) { - self.0.num_internal_pgs_iterations = value + self.0.num_internal_pgs_iterations = value; } #[wasm_bindgen(setter)] pub fn set_minIslandSize(&mut self, value: usize) { @@ -108,16 +98,4 @@ impl RawIntegrationParameters { pub fn set_lengthUnit(&mut self, value: f32) { self.0.length_unit = value } - - pub fn switchToStandardPgsSolver(&mut self) { - self.0 = IntegrationParameters::pgs_legacy() - } - - pub fn switchToSmallStepsPgsSolver(&mut self) { - self.0 = IntegrationParameters::tgs_soft() - } - - pub fn switchToSmallStepsPgsSolverWithoutWarmstart(&mut self) { - self.0 = IntegrationParameters::tgs_soft_without_warmstart() - } } diff --git a/src/dynamics/island_manager.rs b/src/dynamics/island_manager.rs index d252cf20..7b4cfae6 100644 --- a/src/dynamics/island_manager.rs +++ b/src/dynamics/island_manager.rs @@ -24,7 +24,7 @@ impl RawIslandManager { /// set. Called as `f(collider)`. pub fn forEachActiveRigidBodyHandle(&self, f: &js_sys::Function) { let this = JsValue::null(); - for handle in self.0.active_dynamic_bodies() { + for handle in self.0.active_bodies() { let _ = f.call1(&this, &JsValue::from(utils::flat_handle(handle.0))); } } diff --git a/src/dynamics/rigid_body.rs b/src/dynamics/rigid_body.rs index f6b1648b..d7174d77 100644 --- a/src/dynamics/rigid_body.rs +++ b/src/dynamics/rigid_body.rs @@ -403,11 +403,11 @@ impl RawRigidBodySet { /// /// Components set to zero are assumed to be infinite along the corresponding principal axis. #[cfg(feature = "dim2")] - pub fn rbInvPrincipalInertiaSqrt(&self, handle: FlatHandle) -> f32 { + pub fn rbInvPrincipalInertia(&self, handle: FlatHandle) -> f32 { self.map(handle, |rb| { rb.mass_properties() .local_mprops - .inv_principal_inertia_sqrt + .inv_principal_inertia .into() }) } @@ -416,11 +416,11 @@ impl RawRigidBodySet { /// /// Components set to zero are assumed to be infinite along the corresponding principal axis. #[cfg(feature = "dim3")] - pub fn rbInvPrincipalInertiaSqrt(&self, handle: FlatHandle) -> RawVector { + pub fn rbInvPrincipalInertia(&self, handle: FlatHandle) -> RawVector { self.map(handle, |rb| { rb.mass_properties() .local_mprops - .inv_principal_inertia_sqrt + .inv_principal_inertia .into() }) } @@ -453,21 +453,21 @@ impl RawRigidBodySet { }) } - /// The square-root of the world-space inverse angular inertia tensor of the rigid-body, + /// The world-space inverse angular inertia tensor of the rigid-body, /// taking into account rotation locking. #[cfg(feature = "dim2")] - pub fn rbEffectiveWorldInvInertiaSqrt(&self, handle: FlatHandle) -> f32 { + pub fn rbEffectiveWorldInvInertia(&self, handle: FlatHandle) -> f32 { self.map(handle, |rb| { - rb.mass_properties().effective_world_inv_inertia_sqrt.into() + rb.mass_properties().effective_world_inv_inertia.into() }) } - /// The square-root of the world-space inverse angular inertia tensor of the rigid-body, + /// The world-space inverse angular inertia tensor of the rigid-body, /// taking into account rotation locking. #[cfg(feature = "dim3")] - pub fn rbEffectiveWorldInvInertiaSqrt(&self, handle: FlatHandle) -> RawSdpMatrix3 { + pub fn rbEffectiveWorldInvInertia(&self, handle: FlatHandle) -> RawSdpMatrix3 { self.map(handle, |rb| { - rb.mass_properties().effective_world_inv_inertia_sqrt.into() + rb.mass_properties().effective_world_inv_inertia.into() }) } diff --git a/src/dynamics/rigid_body_set.rs b/src/dynamics/rigid_body_set.rs index 70b3297d..83b963e3 100644 --- a/src/dynamics/rigid_body_set.rs +++ b/src/dynamics/rigid_body_set.rs @@ -99,7 +99,7 @@ impl RawRigidBodySet { let mut rigid_body = RigidBodyBuilder::new(rb_type.into()) .enabled(enabled) - .position(pos) + .pose(pos) .gravity_scale(gravityScale) .enabled_translations( translationEnabledX, @@ -162,7 +162,7 @@ impl RawRigidBodySet { let pos = na::Isometry2::from_parts(translation.0.into(), rotation.0); let mut rigid_body = RigidBodyBuilder::new(rb_type.into()) .enabled(enabled) - .position(pos) + .pose(pos) .gravity_scale(gravityScale) .enabled_translations(translationEnabledX, translationEnabledY) .linvel(linvel.0)