A high-performance physics engine for Flutter, powered by Rapier. This plugin provides cross-platform support for 3D physics simulation using Rust and WebAssembly.
- Cross-Platform: Support for Android, iOS, macOS, and Web.
- High Performance: Core physics simulation written in Rust.
- Flexible Physics: Support for various rigid body types (Dynamic, Fixed, Kinematic).
- Force & Impulse: Full support for
addForce,applyImpulse, and theirAtPointvariants. - Velocity Control: Set linear and angular velocities directly for precise state control.
- Colliders: Box, Sphere, Cylinder, Capsule, Cone, and Heightfield colliders.
- Joints Support: Fixed, Spherical, Revolute, Prismatic, and Rope joints with motor support.
- Lifecycle Management: Robust API for adding and removing rigid bodies, colliders, and joints with automatic relationship cleanup.
- CCD: Continuous Collision Detection for high-speed simulation.
- Modern Web Support: Efficient WASM implementation using
dart:js_interop.
Choose one of the following methods to set up the native libraries:
If you prefer not to build from source, you can use the prebuilt binaries provided in the repository.
To build the library from source, follow these steps:
Install Cargo
- 2-1.
curl https://sh.rustup.rs -sSf | sh - 2-2.
source $HOME/.cargo/env - 2-3.
cargo --version
Build Library
- 2-4.
cd native/rapier_ffi - 2-5.
./build.sh
This script will:
- Compile
.sofiles for Android and place them inandroid/src/main/jniLibs. - Compile
.afiles for iOS/macOS and create a.xcframework. - Compile
.wasmfor the Web and place it in the example project.
Initialize the RapierWorld and start simulating:
import 'package:rapier_physics/rapier_physics.dart';
void main() async {
// 1. Initialize the world (asynchronous for WASM support)
final world = RapierWorld();
await world.init();
// 2. Add a static floor
world.addBox(
x: 0, y: 0, z: 0,
hx: 10.0, hy: 0.1, hz: 10.0,
type: RigidBodyType.fixed
);
// 3. Add a dynamic falling box
final box = world.addBox(
x: 0, y: 10, z: 0,
hx: 0.5, hy: 0.5, hz: 0.5
);
// 4. Step the simulation in your game loop
Timer.periodic(Duration(milliseconds: 16), (timer) {
world.step();
print('Box Position: ${box.position}');
});
}RigidBodyType.dynamic: Fully simulated by physics.RigidBodyType.fixed: Static object, does not move.RigidBodyType.kinematicPositionBased: Moved by setting position.RigidBodyType.kinematicVelocityBased: Moved by setting velocity.
lib/: Dart source code and bindings logic.native/rapier_ffi/: Rust source code for the physics bridge.example/: Flutter example application.
This project is licensed under the MIT License.