@rapierphysicsplugin/client 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# @rapierphysicsplugin/client
|
|
2
|
+
|
|
3
|
+
A Babylon.js physics engine plugin powered by [Rapier](https://rapier.rs/) with built-in networked multiplayer support. Use standard Babylon.js `PhysicsAggregate` / `PhysicsBody` APIs and get server-authoritative physics synchronization automatically.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @rapierphysicsplugin/client @rapierphysicsplugin/shared
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Peer dependencies
|
|
12
|
+
|
|
13
|
+
- `@babylonjs/core` >= 6.0.0
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { Engine, Scene, Vector3, MeshBuilder, PhysicsAggregate, PhysicsShapeType } from '@babylonjs/core';
|
|
19
|
+
import { NetworkedRapierPlugin } from '@rapierphysicsplugin/client';
|
|
20
|
+
import { loadRapier, detectSIMDSupport, ComputeBackend } from '@rapierphysicsplugin/shared';
|
|
21
|
+
|
|
22
|
+
// 1. Load Rapier WASM
|
|
23
|
+
const backend = detectSIMDSupport() ? ComputeBackend.WASM_SIMD : ComputeBackend.WASM_COMPAT;
|
|
24
|
+
const RAPIER = await loadRapier({ backend });
|
|
25
|
+
|
|
26
|
+
// 2. Create Babylon.js scene
|
|
27
|
+
const engine = new Engine(canvas, true);
|
|
28
|
+
const scene = new Scene(engine);
|
|
29
|
+
|
|
30
|
+
// 3. Create plugin and connect to server
|
|
31
|
+
const gravity = new Vector3(0, -9.81, 0);
|
|
32
|
+
const plugin = new NetworkedRapierPlugin(RAPIER, gravity, {
|
|
33
|
+
serverUrl: 'ws://localhost:8080',
|
|
34
|
+
roomId: 'my-room',
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
scene.enablePhysics(gravity, plugin);
|
|
38
|
+
await plugin.connect(scene);
|
|
39
|
+
|
|
40
|
+
// 4. Create physics bodies — standard Babylon.js API
|
|
41
|
+
const box = MeshBuilder.CreateBox('box', { size: 1 }, scene);
|
|
42
|
+
box.position.set(0, 5, 0);
|
|
43
|
+
new PhysicsAggregate(box, PhysicsShapeType.BOX, { mass: 1, friction: 0.5, restitution: 0.3 }, scene);
|
|
44
|
+
|
|
45
|
+
// The plugin automatically syncs bodies with the server.
|
|
46
|
+
// Remote clients' bodies appear in your scene automatically.
|
|
47
|
+
|
|
48
|
+
// 5. Send input (e.g., apply impulse on click)
|
|
49
|
+
plugin.sendInput([{
|
|
50
|
+
type: 'applyImpulse',
|
|
51
|
+
bodyId: box.metadata.bodyId,
|
|
52
|
+
data: { impulse: { x: 0, y: 10, z: 0 } },
|
|
53
|
+
}]);
|
|
54
|
+
|
|
55
|
+
// 6. Listen for events
|
|
56
|
+
plugin.onStateUpdate((state) => {
|
|
57
|
+
console.log(`Tick ${state.tick}, ${state.bodies.length} bodies updated`);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
plugin.onCollisionEvents((events) => {
|
|
61
|
+
events.forEach(e => console.log(`Collision: ${e.bodyId1} <-> ${e.bodyId2}`));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
plugin.onSimulationReset(() => {
|
|
65
|
+
// Re-create local bodies (ground, etc.)
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// 7. Render loop
|
|
69
|
+
engine.runRenderLoop(() => scene.render());
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Supported Shape Types
|
|
73
|
+
|
|
74
|
+
- `PhysicsShapeType.BOX`
|
|
75
|
+
- `PhysicsShapeType.SPHERE`
|
|
76
|
+
- `PhysicsShapeType.CAPSULE`
|
|
77
|
+
- `PhysicsShapeType.MESH`
|
|
78
|
+
|
|
79
|
+
## Input Actions
|
|
80
|
+
|
|
81
|
+
Send physics commands to the server via `plugin.sendInput()`:
|
|
82
|
+
|
|
83
|
+
| Action | Description |
|
|
84
|
+
|--------|-------------|
|
|
85
|
+
| `applyForce` | Apply continuous force to a body |
|
|
86
|
+
| `applyImpulse` | Apply instantaneous impulse (optionally at a point) |
|
|
87
|
+
| `setLinearVelocity` | Set a body's linear velocity |
|
|
88
|
+
| `setAngularVelocity` | Set a body's angular velocity |
|
|
89
|
+
| `setPosition` | Teleport a body to a position |
|
|
90
|
+
|
|
91
|
+
## Architecture
|
|
92
|
+
|
|
93
|
+
The plugin uses a **server-authoritative** model:
|
|
94
|
+
|
|
95
|
+
- **Local physics are skipped** — the server runs the simulation
|
|
96
|
+
- **State interpolation** — remote bodies are smoothly interpolated between server snapshots
|
|
97
|
+
- **Clock synchronization** — RTT-based time sync keeps client and server aligned
|
|
98
|
+
- **Delta compression** — only changed body states are sent over the wire
|
|
99
|
+
|
|
100
|
+
### Exported Classes
|
|
101
|
+
|
|
102
|
+
| Class | Purpose |
|
|
103
|
+
|-------|---------|
|
|
104
|
+
| `NetworkedRapierPlugin` | Main entry point — Babylon.js plugin with networking |
|
|
105
|
+
| `RapierPlugin` | Standalone Babylon.js Rapier plugin (no networking) |
|
|
106
|
+
| `PhysicsSyncClient` | Low-level WebSocket sync client |
|
|
107
|
+
| `ClockSyncClient` | Network time synchronization |
|
|
108
|
+
| `StateReconciler` | Manages local vs. remote body state |
|
|
109
|
+
| `Interpolator` | Smooth interpolation/extrapolation of remote bodies |
|
|
110
|
+
| `InputManager` | Input batching and history |
|
|
111
|
+
|
|
112
|
+
## Debug Info
|
|
113
|
+
|
|
114
|
+
Access runtime stats for debug overlays:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
const reconciler = plugin.getReconciler();
|
|
118
|
+
const interpolator = reconciler.getInterpolator();
|
|
119
|
+
const clockSync = plugin.getClockSync();
|
|
120
|
+
|
|
121
|
+
const stats = interpolator.getStats(); // interpolated/extrapolated/stale counts
|
|
122
|
+
const rtt = clockSync.getRTT(); // round-trip time in ms
|
|
123
|
+
const offset = clockSync.getClockOffset();
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Dependencies
|
|
127
|
+
|
|
128
|
+
- `@babylonjs/core` (peer) — Babylon.js engine
|
|
129
|
+
- `@dimforge/rapier3d-compat` — Rapier WASM physics
|
|
130
|
+
- `@rapierphysicsplugin/shared` — types and serialization
|