Godot Rapier Physics

repository·main·Indexed 21 days ago

https://github.com/appsinacup/godot-rapier-physics

A 2D and 3D physics engine replacement for the Godot game engine powered by Rapier and Salva. Version 0.8.40 provides improved stability, performance, determinism, and state serialization. It can be installed as a Godot plugin or included as a Rust dependency for GDExtensions. The library includes specialized variants for parallel SIMD solvers and cross-platform determinism, as well as support for 2D fluid simulation via Fluid2D.

Tokens
12.9K
Snippets
27
Records
44
Agent score
75%

What's inside godot-rapier

  1. How the Godot Rapier data architecture works

    main

    The plugin organizes data into two distinct layers to bridge Godot and the Rapier physics engine:

    1. Godot Data Layer: This layer maps directly to the data sent from Godot to the plugin. It uses a structure of stateless data and stateful data (e.g., RapierSpace and RapierSpaceState).
    2. Rapier Data Layer: This layer contains data that has been converted from the Godot format to match the requirements of the Rapier library (e.g., PhysicsEngine, PhysicsWorld, and PhysicsObjects).

    For performance optimization, all this data is managed within a Singleton. The Singleton maintains mappings between Godot's Rid (Resource ID) and the internal plugin indices, ensuring efficient lookups across the two layers.

  2. The role of PhysicsEngine in the Rapier Data Layer

    main

    In the Rapier Data Layer, PhysicsEngine acts as the top-level container for the physics simulation. It manages:

    • physics_worlds: An Arena containing PhysicsWorld instances, indexed by Index.
    • shapes: An Arena containing SharedShape instances, indexed by Index.

    PhysicsEngine serves as the entry point for accessing the various physics worlds and shared resources used by the simulation.

  3. Workaround for 6DOF joint limit behavior differences

    main

    As of Rapier version 0.32.0, Rapier cannot match the specific limit behavior of the Jolt 6DOF joint using a single joint. Jolt uses swing/twist axes with a pyramid constraint on the swing, which Rapier's single-joint implementation does not currently replicate.

    To achieve similar 6DOF limit behavior in Rapier, you can use one of the following workarounds:

    1. Compound Joints: Combine two joints into one to better approximate the desired limit behavior (see the compound 6dof sample scene).
    2. External Colliders: Implement limits manually by using external colliders to physically stop the rigid body at the desired limit points.
  4. Install Godot Rapier Physics as a Godot Plugin

    main

    You can install Godot Rapier Physics as a drop-in replacement for the default Godot physics engine using two methods:

    Download the specific variant you need from the Godot Asset Store. For most general use cases, use the Faster Version (Parallel SIMD Solver).

    Available Variants:

    Manual

    1. Download the latest GitHub release.
    2. Move the addons folder from the release into your Godot project's addons folder.

    Activation

    After installation, you must enable the engine in Godot settings:

    1. Go to Advanced Settings -> Physics -> 2D (or 3D).
    2. Change the Physics Engine property to Rapier2D or Rapier3D.
  5. Use Godot Rapier as a Rust dependency

    main

    If you are building a Godot extension using godot-rust (gdext), you can include Rapier as a dependency. You must select features that match the variant you intend to ship and use exactly one Godot API feature (api-4-4, api-4-5, api-4-6, or api-4-7).

    Cargo Configuration

    Add the following to your Cargo.toml. Example for the 2D fast parallel variant:

    [dependencies]
    godot-rapier = { git = "https://github.com/appsinacup/godot-rapier-physics.git", tag = "v0.8.40", features = ["single-dim2", "serde-serialize", "simd-stable", "parallel", "experimental-threads", "register-docs", "api-4-7"] }

    Web/Emscripten Support

    For web builds, replace experimental-threads with:

    • experimental-wasm: For threaded web builds.
    • experimental-wasm-nothreads: For no-thread web builds (this includes experimental-wasm).

    Integration with other GDExtensions

    Because Godot only runs one main ExtensionLibrary, you must set GDRUST_MAIN_EXTENSION to your extension's type and manually forward Rapier's initialization stages.

    Warning: Do not load the standalone Godot Rapier addon in the same project where you are bundling it via a Rust GDExtension to avoid duplicate class registration.

    [dependencies]
    godot-rapier = { git = "https://github.com/appsinacup/godot-rapier-physics.git", tag = "v0.8.40", features = ["single-dim2"] }
  6. Use 3D joint test samples for verification

    main

    The interactive_3d_joint_tests directory contains minimal 3D scenes designed to help users and contributors toy with 3D joints and verify their behavior. There is a sample scene provided for every Joint3D type available in Godot.

    Note that these are primarily intended as convenience tools for contributors working on joint code and may be removed if they lose utility.

  7. Use Fluid2D for 2D fluid simulation

    main

    The Fluid2D node (inheriting from Node2D) is used to simulate fluid particles in a 2D environment. It manages particle positions, velocities, density, and lifetime. You can interact with the fluid by setting particle points, adding/deleting particles, or querying particle data like velocities and accelerations.

    Key properties:

    • radius: The radius of individual fluid particles.
    • density: The density of the fluid particles.
    • lifetime: The lifetime of the fluid particles.
    • effects: An array of Resource objects to apply effects to the fluid.
    • collision_layer / collision_mask: Standard 2D physics collision settings.
    • debug_draw: A boolean to enable visual debugging of particle positions.
    # Example: Setting up a basic fluid node in GDScript
    var fluid = Fluid2D.new()
    add_child(fluid)
    fluid.density = 1.5
    fluid.lifetime = 5.0
  8. Use Fluid3D for 3D fluid simulation

    main

    Fluid3D is a Node3D used to simulate fluids in 3D space. It manages a collection of fluid particles with properties like density, lifetime, and collision layers. You can populate the fluid by manually setting points, adding points with velocities, or using built-in generators for box and sphere shapes.

    # Example: Creating a sphere of fluid particles
    var fluid = Fluid3D.new()
    add_child(fluid)
    
    # Create points in a sphere shape with a radius of 5
    var sphere_points = fluid.create_sphere_points(5)
    fluid.set_points(sphere_points)
    
    # Set fluid properties
    fluid.density = 1.5
    fluid.lifetime = 10.0
  9. Create a RapierPhysicsServer2D singleton

    main

    To use the Rapier physics engine within Godot, you must create a RapierPhysicsServer2D instance. This is done via the RapierPhysicsServerFactory2D class. Note that you should not instantiate the server directly; always use the factory method.

    # Example of how one might access the server via the factory in GDScript
    var rapier_server = RapierPhysicsServerFactory2D.create_server()
  10. Initialize the RapierPhysicsServer3D singleton

    main

    The RapierPhysicsServer3D is the main physics server singleton implemented for Rapier Physics. It extends Godot's PhysicsServer3D to provide Rapier-specific capabilities.

    Note: You should not instantiate RapierPhysicsServer3D directly. Instead, use the RapierPhysicsServerFactory3D to create the singleton instance.

    # Example of how the factory is intended to be used internally or via script
    var rapier_server = RapierPhysicsServerFactory3D.create_server()
  11. Implement Rapier initialization in a Rust GDExtension

    main

    When bundling godot-rapier inside your own Rust extension, you must implement the on_stage_init and on_stage_deinit methods to register the Rapier server and classes. Use RapierPhysics3DExtensionLibrary for 3D projects or RapierPhysics2DExtensionLibrary for 2D projects.

    use godot::prelude::*;
    use godot_rapier::RapierPhysics3DExtensionLibrary;
    
    struct MyExtension;
    
    #[gdextension]
    unsafe impl ExtensionLibrary for MyExtension {
        fn min_level() -> InitLevel {
            InitLevel::Servers
        }
    
        fn on_stage_init(level: InitStage) {
            RapierPhysics3DExtensionLibrary::on_stage_init(level);
        }
    
        fn on_stage_deinit(level: InitStage) {
            RapierPhysics3DExtensionLibrary::on_stage_deinit(level);
        }
    }
  12. Reference: Godot Rapier Rust Feature Sets

    main

    The following feature flags correspond to the available addon variants for use in Cargo.toml.

    | Variant | Features |
    | - | - |
    | 2D fast parallel | `single-dim2`, `serde-serialize`, `simd-stable`, `parallel`, `experimental-threads`, `register-docs`, `api-4-7` |
    | 3D fast parallel | `single-dim3`, `serde-serialize`, `simd-stable`, `parallel`, `experimental-threads`, `register-docs`, `api-4-7` |
    | 2D enhanced deterministic | `single-dim2`, `serde-serialize`, `enhanced-determinism`, `experimental-threads`, `register-docs`, `api-4-7` |
    | 3D enhanced deterministic | `single-dim3`, `serde-serialize`, `enhanced-determinism`, `experimental-threads`, `register-docs`, `api-4-7` |