Skip to content

VigorFox/PhysX_AVBD

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

82 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NVIDIA PhysX + AVBD Solver

🔬 Research Fork: Experimental AVBD (Augmented Variable Block Descent) constraint solver integrated into NVIDIA PhysX SDK.

Copyright (c) 2008-2025 NVIDIA Corporation. All rights reserved. BSD-3-Clause License.

⚠️ Project Status

Status Legend: Integrated = merged into main code path; Accepted = integrated and fully validated by current acceptance gates; Early = prototype path exists but is not acceptance-validated and still has major gaps; Pending = not complete or acceptance not closed.

Feature Status Notes
Rigid Body Solver ✅ Accepted Contacts + unified AVBD local solve
D6 Unified Joint ✅ Accepted All joint types (Spherical, Fixed, Revolute, Prismatic) unified into single D6 constraint path
Joint Limits ✅ Accepted Revolute angle, Prismatic linear, Spherical cone, D6 per-axis
Motor Drive ✅ Accepted Post-solve torque motor for revolute; SLERP drive for D6
Gear Joint ✅ Accepted Velocity-ratio constraint with post-solve motor
Standalone Alignment ✅ Accepted Rigid/joint D6 path is aligned with avbd_standalone; standalone soft body has progressed further than the current PhysX port
Regression Baseline ✅ Accepted Standalone: 118/118 (101 rigid/artic + 17 soft body); PhysX articulation: 29/29
O(M) Constraint Lookup ✅ Accepted Eliminates O(N²) complexity
Multi-threaded Islands ✅ Accepted Per-island constraint mappings
Friction Model ✅ Accepted Coulomb cone, per-material coefficients from PxContactPatch
Soft Body / Deformable ⚠️ Early Prototype AVBD path exists, but it is still early-stage and currently has major performance problems
Custom Joint ⏳ Pending Custom constraint callbacks unsupported
Rack & Pinion ⏳ Pending RackAndPinionJoint unsupported
Mimic Joint ⏳ Pending MimicJoint unsupported
Articulation ✅ Accepted Pure AVBD penalty-based, 29/29 tests, per-island iterations
Sleep / Wake ⏳ Pending Not implemented

For research and evaluation only. Not production-ready.

Recent Progress (2026-03)

Articulation Solver (NEW)

Articulation support is now fully implemented using a pure AVBD penalty-based architecture — no Featherstone dependency. All articulation internal joints are solved as AL constraint rows in the same block descent loop as contacts and external D6 joints.

Note: AVBD articulation/joint solving is maximal-coordinate oriented on the solver side, but the public API still uses PxArticulationReducedCoordinate naming because upstream PhysX 5 removed the older solver-neutral PxArticulation abstraction layer.

Key achievements:

  • 29/29 PhysX tests pass including scissor lift with closed kinematic loops, loaded boxes, and 10s stability.
  • Iteration-efficiency pass completed: the full PhysX articulation regression now also passes at 10 solver iterations. This reduction came from D6/articulation lambda warm-starting, conservative early-stop, targeted articulation iteration diagnostics, and a solver-side fix for eACCELERATION drive semantics.
  • 12 bugs fixed during integration: motion encoding (2-bit-per-axis), position drive error computation, eFIX penalty boost, iteration count byte order, and more.
  • Per-island adaptive iterations: Articulations use setSolverIterationCounts(N) for higher iteration budgets; contact-only islands default to 8 iterations.
  • Exceeds Featherstone hybrid ceiling: The alternating-solve lag in Featherstone coupling was the dominant error source for strongly coupled systems. Unified penalty solving eliminates this boundary.
  • Standalone: full suite now passes at 118/118 (101 rigid/artic + 17 soft body). The rigid/artic lineage still includes convergence acceleration (Anderson Acceleration 47%, Chebyshev 29%), ID extraction via λ*, solver-is-IK, and mimic joints.

Articulation Iteration Efficiency (2026-04)

Recent work focused on lowering the articulation iteration budget globally instead of only tuning a single snippet scene.

  • Warm-start extension: D6/articulation joints now reuse cached AL multipliers across frames, not just contacts.
  • Measurement-first diagnostics: PHYSX_AVBD_ITER_DIAG, PHYSX_AVBD_ITER_DIAG_EVERY, and PHYSX_AVBD_ITER_DIAG_SEQUENTIAL expose requested vs executed iterations, joint-row composition, and dominant lambda sources so bottlenecks can be localized before retuning.
  • Drive semantic fix: articulation-internal PxArticulationDriveType::eACCELERATION is now handled in the solver using response-scaled implicit coefficients instead of being approximated only in constraint prep.
  • Current verified floor: SnippetAvbdArticulation passes as a full suite at 10 iterations. 8 iterations still fails in the loaded Scissor Lift case, so 10 is the current repository-wide verified articulation floor.

D6 Unification

All joint types have been unified into a single D6 constraint path. Per-type independent solvers (Spherical, Fixed, Revolute, Prismatic) have been replaced by one shared addD6Contribution() / updateD6Dual() pipeline, with joint behavior determined entirely by motion masks (LOCKED/FREE/LIMITED per DOF).

Key changes:

  • Architecture: ~400 lines of redundant per-type constraint code removed; all joints route through unified D6 primal + dual path.
  • Angular constraints: Cross-product axis alignment for revolute-pattern D6 joints, replacing quaternion tangent-space error. Immune to twist-angle amplification at large rotations.
  • Angular error: Axis-angle decomposition (2·acos(w)·axis) replaces tangent-space 2·vec(errQ), accurate at large angles.
  • Motor: Post-solve torque motor decoupled from ADMM constraint Hessian, replacing in-iteration AL velocity drive.
  • Gear joint: Dual update moved inside ADMM iteration loop; NaN from driveForceLimit overflow fixed.
  • Cone limit: Per-body joint frame axes derived from localFrameA/localFrameB, replacing shared axis.
  • Joint frames: localFrameB derived from initial relative rotation at joint creation. All factory methods updated.
  • Standalone sync: rigid/joint D6 behavior remains aligned with avbd_standalone, while standalone soft body has already moved to a VBD+AVBD path that is not yet mirrored by the current PhysX port.

Friction Integration

Friction was already fully implemented in the AVBD solver (3-DOF contact model: 1 normal + 2 tangent), but PhysX contact preparation hardcoded friction = 0.5f and restitution = 0.0f instead of reading from materials.

Key changes:

  • Material read-through: constraint.friction and constraint.restitution now read from PxContactPatch::dynamicFriction / restitution (combined by narrowphase).
  • Tangent basis: Aligned with standalone — PxAbs(normal.y) > 0.9f branch for robustness.
  • Standalone tests: 18 friction-specific tests (slope sliding, anisotropy, Coulomb cone, geometric mean combining, warmstart, penalty growth, etc.).

Soft Body / Deformable Status (EARLY)

The AVBD soft body / deformable path is still in an early prototype stage.

  • Functional pieces exist, including AVBD deformable snippets and the current OGC-based collision path.
  • avbd_standalone soft body is already accepted with a full 118/118 standalone pass set (101 rigid/artic + 17 soft body), but that maturity has not yet carried over to the current PhysX port.
  • It is not part of the accepted regression baseline summarized above.
  • Current implementation has major performance problems and should be treated as a research path, not a production-ready or even feature-complete baseline.
  • Near-term work is expected to focus on architecture cleanup, data layout, and performance before soft body results should be interpreted as representative.

Current Validation Snapshot

  • ✅ Standalone full suite passes (118/118: 101 rigid/artic + 17 soft body).
  • ✅ PhysX articulation regression passes (29/29 tests, 15 consecutive deterministic runs).
  • ✅ PhysX articulation regression also passes at PHYSX_AVBD_SOLVER_ITERS=10; this is the current verified global floor.
  • ✅ PhysX debug build succeeds with all Snippets.
  • SnippetChainmail remains integrated for extreme impact and dense-joint stress regression.
  • ✅ All joint types validated: Spherical chain, breakable Fixed, damped D6, limited Prismatic, limited Revolute.
  • ✅ Gear joint stable (no NaN, no oscillation, no twist amplification).
  • ✅ Friction reads per-material coefficients; Coulomb cone + augmented Lagrangian validated.
  • ✅ Scissor lift with closed kinematic loops and loaded boxes: stable 10s.
  • ✅ Per-island adaptive iteration override: articulations get high iterations, contacts get low.
  • ⚠️ Full articulation regression still fails at 8 iterations in the loaded Scissor Lift path; further down-pressure is still pending.
  • ⚠️ Soft body / deformable AVBD is still early-stage and currently has major performance issues; it is not included in the accepted baseline above.

SnippetChainmail Demo

SnippetChainmail.mp4

Why AVBD?

PhysX's built-in TGS/PGS are velocity-level iterative solvers that hit fundamental limits in several scenarios:

Problem TGS/PGS Limitation AVBD Direction
High mass-ratio joints Condition number explosion, rubber-banding Augmented Lagrangian + local Hessian solve
Multiplayer sync Velocity integration accumulates FP error Position-level solve with stronger state consistency
Cloth & soft body Requires separate solver pipelines Position-level framework is more naturally extensible

AVBD introduces a unified position-level constraint solving framework targeting:

  1. Stable high mass-ratio interaction chains.
  2. Whole-scene robustness under mixed contact/joint constraints.
  3. Better deterministic behavior for server-authoritative simulation.
  4. Future rigid/soft-body unification on a common optimization-style solver structure.

Roadmap Snapshot

Contact AL stability (DONE)         D6 Unified Joint System (DONE)
  Rigid body contacts stable      ->  All joints unified into D6 path
  AVBD usable as whole-scene solver   Spherical/Fixed/Revolute/Prismatic/D6/Gear: accepted
            |                                    |
  Lambda warm-starting (DONE)        Articulation Solver (DONE)
  Iteration-efficiency tuning        Pure AVBD penalty-based, 29/29 PhysX tests
            |                        Per-island adaptive iterations
            |                                    |
Soft body / performance / GPU path (EARLY)
	SOA refactoring, multiplayer determinism

Solver Architecture

Unified AVBD Hessian Approach

The solver accumulates contacts and joints into a per-body local system (typically 6x6), then solves via LDLT:

For each body i:
	H = M/h^2 * I_6x6
	g = M/h^2 * (x_i - x_tilde)

	For each contact/joint row:
		H += rho_eff * J^T J
		g += J * (rho_eff * C + lambda)

	Dual update (stabilized AL):
		rhoDual = min(Mh^2, rho^2/(rho + Mh^2))
		lambda  = decay * lambda + rhoDual * C

	delta = LDLT_solve(H, g)
	x_i -= delta

Key Design Decisions

Decision Rationale
Unified D6 joint path All joint types (Spherical, Fixed, Revolute, Prismatic) map to a single D6 constraint with motion masks.
Cross-product axis alignment Revolute-pattern angular constraints use twistA x twistB instead of quaternion error, avoiding twist amplification.
Post-solve motor Motor torque applied after ADMM iterations, decoupled from constraint Hessian for stability.
Stabilized AL dual for joints Bounded dual step + decay (rhoDual, lambdaDecay) reduces overshoot while retaining AL memory.
Prismatic force-6x6 on touch Prevents instability from 3x3 decoupling under strong position-rotation coupling.
Standalone/PhysX algorithm parity Rigid/joint paths share the same core constraint formulation and dual update logic; standalone soft body has advanced to a VBD+AVBD path that is not yet fully mirrored in PhysX.

AVBD Solver Overview

AVBD is a position-based constraint solver using:

  • Block Coordinate Descent - Per-body 6x6 local system solve
  • Augmented Lagrangian - Multiplier updates for constraint satisfaction
  • Island-level Parallelism - Independent islands solve concurrently

Comparison with TGS/PGS

Property PGS TGS AVBD
Solve Level Velocity Velocity Position
Convergence Linear Sublinear Quadratic
Stack Stability Fair Good Excellent
Cost per Iteration Low Medium Medium-High

Quick Start

Build

cd physx
./generate_projects.bat  # Windows
./generate_projects.sh   # Linux

Enable AVBD

PxSceneDesc sceneDesc(physics->getTolerancesScale());
sceneDesc.solverType = PxSolverType::eAVBD;

Source Structure

physx/source/lowleveldynamics/src/
├── DyAvbdSolver.h/cpp            # Core solver (contact-only path)
├── DyAvbdSolverJointPath.cpp     # Solver joint path (solveWithJoints entry)
├── DyAvbdJointProjection.h/cpp   # Per-joint-type constraint projection & multiplier update
├── DyAvbdDynamics.h/cpp          # PhysX integration & frame orchestration
├── DyAvbdDynamicsPrep.cpp        # Contact & joint constraint preparation
├── DyAvbdTasks.h/cpp             # Multi-threading
├── DyAvbdTypes.h                 # Config & data structures
├── DyAvbdConstraint.h            # Constraint definitions
└── DyAvbdSolverBody.h/cpp        # Body state

Profiling

PVD Profile Zones available:

  • AVBD.update - Total update time
  • AVBD.solveWithJoints - Main solver loop
  • AVBD.blockDescentWithJoints - Constraint iterations
  • AVBD.updateLambda - Multiplier updates

Known Limitations

  1. No Sleep/Wake - Bodies remain active
  2. CPU only - No GPU acceleration
  3. Articulation low-budget edge cases - The current verified full-suite floor is 10 iterations; the loaded Scissor Lift case still fails at 8
  4. Soft body performance - The current AVBD soft body / deformable path remains early-stage and has major performance problems

Original PhysX Documentation

License

NVIDIA PhysX BSD-3-Clause. See LICENSE.md.

About

NVIDIA PhysX SDK With Experimental Augmented Vertex Block Descent(AVBD) Solver

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • C++ 73.2%
  • Python 12.0%
  • Cuda 6.2%
  • C 6.0%
  • HLSL 1.0%
  • CMake 0.9%
  • Other 0.7%