@lagless/physics2d 0.0.39
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/LICENSE +26 -0
- package/README.md +237 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/collision-events-2d.d.ts +6 -0
- package/dist/lib/collision-events-2d.d.ts.map +1 -0
- package/dist/lib/collision-events-2d.js +8 -0
- package/dist/lib/collision-events-2d.js.map +1 -0
- package/dist/lib/physics-config-2d.d.ts +9 -0
- package/dist/lib/physics-config-2d.d.ts.map +1 -0
- package/dist/lib/physics-config-2d.js +13 -0
- package/dist/lib/physics-config-2d.js.map +1 -0
- package/dist/lib/physics-runner-2d.d.ts +17 -0
- package/dist/lib/physics-runner-2d.d.ts.map +1 -0
- package/dist/lib/physics-runner-2d.js +47 -0
- package/dist/lib/physics-runner-2d.js.map +1 -0
- package/dist/lib/physics-simulation-2d.d.ts +7 -0
- package/dist/lib/physics-simulation-2d.d.ts.map +1 -0
- package/dist/lib/physics-simulation-2d.js +8 -0
- package/dist/lib/physics-simulation-2d.js.map +1 -0
- package/dist/lib/physics-step-sync-2d.d.ts +35 -0
- package/dist/lib/physics-step-sync-2d.d.ts.map +1 -0
- package/dist/lib/physics-step-sync-2d.js +43 -0
- package/dist/lib/physics-step-sync-2d.js.map +1 -0
- package/dist/lib/physics-world-manager-2d.d.ts +46 -0
- package/dist/lib/physics-world-manager-2d.d.ts.map +1 -0
- package/dist/lib/physics-world-manager-2d.js +148 -0
- package/dist/lib/physics-world-manager-2d.js.map +1 -0
- package/dist/lib/rapier-types-2d.d.ts +110 -0
- package/dist/lib/rapier-types-2d.d.ts.map +1 -0
- package/dist/lib/rapier-types-2d.js +7 -0
- package/dist/lib/rapier-types-2d.js.map +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Creative Commons Attribution-NonCommercial 4.0 International
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Lagless
|
|
4
|
+
|
|
5
|
+
This work is licensed under the Creative Commons
|
|
6
|
+
Attribution-NonCommercial 4.0 International License.
|
|
7
|
+
|
|
8
|
+
You are free to:
|
|
9
|
+
|
|
10
|
+
Share — copy and redistribute the material in any medium or format
|
|
11
|
+
Adapt — remix, transform, and build upon the material
|
|
12
|
+
|
|
13
|
+
Under the following terms:
|
|
14
|
+
|
|
15
|
+
Attribution — You must give appropriate credit, provide a link to
|
|
16
|
+
the license, and indicate if changes were made. You may do so in
|
|
17
|
+
any reasonable manner, but not in any way that suggests the licensor
|
|
18
|
+
endorses you or your use.
|
|
19
|
+
|
|
20
|
+
NonCommercial — You may not use the material for commercial purposes.
|
|
21
|
+
|
|
22
|
+
No additional restrictions — You may not apply legal terms or
|
|
23
|
+
technological measures that legally restrict others from doing
|
|
24
|
+
anything the license permits.
|
|
25
|
+
|
|
26
|
+
Full license text: https://creativecommons.org/licenses/by-nc/4.0/legalcode
|
package/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# @lagless/physics2d
|
|
2
|
+
|
|
3
|
+
Rapier 2D physics integration for the lagless ECS framework. Deterministic stepping, snapshot/rollback, collision events, and DI-ready runner.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @lagless/physics2d @dimforge/rapier2d-compat
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Peer dependency: `@dimforge/rapier2d-compat >= 0.14.0`
|
|
12
|
+
|
|
13
|
+
## Architecture
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
@lagless/physics-shared (BodyType, ColliderEntityMap, CollisionLayers, CollisionEventsBase, PhysicsSimulationBase)
|
|
17
|
+
│
|
|
18
|
+
▼
|
|
19
|
+
@lagless/physics2d (2D wrappers: PhysicsWorldManager2d, PhysicsStepSync2d, PhysicsRunner2d, ...)
|
|
20
|
+
│
|
|
21
|
+
└── peer: @dimforge/rapier2d-compat
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## ECS Schema (codegen)
|
|
25
|
+
|
|
26
|
+
Set `simulationType: 'physics2d'` in your `ecs.yaml`. Codegen auto-prepends:
|
|
27
|
+
|
|
28
|
+
- **Transform2d** — 6 float32 fields: `positionX/Y`, `rotation` (radians), `prevPositionX/Y`, `prevRotation`
|
|
29
|
+
- **PhysicsRefs** — `bodyHandle: float64`, `colliderHandle: float64`, `bodyType: uint8`, `collisionLayer: uint16`
|
|
30
|
+
- **PhysicsRefsFilter** — filter matching `[PhysicsRefs, Transform2d]`
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
simulationType: physics2d
|
|
34
|
+
|
|
35
|
+
components:
|
|
36
|
+
Velocity:
|
|
37
|
+
x: float32
|
|
38
|
+
y: float32
|
|
39
|
+
|
|
40
|
+
Health:
|
|
41
|
+
value: uint16
|
|
42
|
+
|
|
43
|
+
singletons:
|
|
44
|
+
GameState:
|
|
45
|
+
phase: uint8
|
|
46
|
+
|
|
47
|
+
filters:
|
|
48
|
+
VelocityFilter:
|
|
49
|
+
include: [Velocity, Transform2d]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
### Runner Setup
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import RAPIER from '@dimforge/rapier2d-compat';
|
|
58
|
+
import { PhysicsConfig2d } from '@lagless/physics2d';
|
|
59
|
+
import { MyGameRunner } from './code-gen/my-game.runner.js';
|
|
60
|
+
|
|
61
|
+
await RAPIER.init();
|
|
62
|
+
|
|
63
|
+
const runner = new MyGameRunner(
|
|
64
|
+
ecsConfig,
|
|
65
|
+
inputProvider,
|
|
66
|
+
[PhysicsSystem, MovementSystem],
|
|
67
|
+
[HitSignal],
|
|
68
|
+
RAPIER,
|
|
69
|
+
new PhysicsConfig2d({ gravityY: -9.81, substeps: 2 }),
|
|
70
|
+
);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Physics System Pattern
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
@ECSSystem()
|
|
77
|
+
class PhysicsSystem implements IECSSystem {
|
|
78
|
+
constructor(
|
|
79
|
+
private readonly _transform: Transform2d,
|
|
80
|
+
private readonly _physicsRefs: PhysicsRefs,
|
|
81
|
+
private readonly _filter: PhysicsRefsFilter,
|
|
82
|
+
private readonly _worldManager: PhysicsWorldManager2d,
|
|
83
|
+
private readonly _physicsConfig: PhysicsConfig2d,
|
|
84
|
+
) {}
|
|
85
|
+
|
|
86
|
+
update(tick: number): void {
|
|
87
|
+
// 1. Save previous transforms (for interpolation)
|
|
88
|
+
PhysicsStepSync2d.savePrevTransforms(this._filter, this._transform);
|
|
89
|
+
|
|
90
|
+
// 2. Push kinematic bodies from ECS → Rapier
|
|
91
|
+
PhysicsStepSync2d.syncKinematicToRapier(
|
|
92
|
+
this._filter, this._physicsRefs, this._transform, this._worldManager,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// 3. Step physics
|
|
96
|
+
this._worldManager.step();
|
|
97
|
+
|
|
98
|
+
// 4. Pull dynamic bodies from Rapier → ECS
|
|
99
|
+
PhysicsStepSync2d.syncDynamicFromRapier(
|
|
100
|
+
this._filter, this._physicsRefs, this._transform, this._worldManager,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Spawning a Physics Entity
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
@ECSSystem()
|
|
110
|
+
class SpawnSystem implements IECSSystem {
|
|
111
|
+
constructor(
|
|
112
|
+
private readonly _entities: EntitiesManager,
|
|
113
|
+
private readonly _transform: Transform2d,
|
|
114
|
+
private readonly _physicsRefs: PhysicsRefs,
|
|
115
|
+
private readonly _worldManager: PhysicsWorldManager2d,
|
|
116
|
+
) {}
|
|
117
|
+
|
|
118
|
+
spawnBall(x: number, y: number, radius: number): number {
|
|
119
|
+
const entity = this._entities.create();
|
|
120
|
+
|
|
121
|
+
const body = this._worldManager.createDynamicBody();
|
|
122
|
+
body.setTranslation({ x, y }, true);
|
|
123
|
+
const collider = this._worldManager.createBallCollider(radius, body);
|
|
124
|
+
|
|
125
|
+
this._physicsRefs.bodyHandle.set(entity, body.handle);
|
|
126
|
+
this._physicsRefs.colliderHandle.set(entity, collider.handle);
|
|
127
|
+
this._physicsRefs.bodyType.set(entity, BodyType.DYNAMIC);
|
|
128
|
+
|
|
129
|
+
this._transform.positionX.set(entity, x);
|
|
130
|
+
this._transform.positionY.set(entity, y);
|
|
131
|
+
this._transform.rotation.set(entity, 0);
|
|
132
|
+
// Always set prev = current to avoid interpolation jump
|
|
133
|
+
this._transform.prevPositionX.set(entity, x);
|
|
134
|
+
this._transform.prevPositionY.set(entity, y);
|
|
135
|
+
this._transform.prevRotation.set(entity, 0);
|
|
136
|
+
|
|
137
|
+
this._worldManager.registerCollider(collider.handle, entity);
|
|
138
|
+
return entity;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Differences from physics3d
|
|
144
|
+
|
|
145
|
+
| Aspect | physics2d | physics3d |
|
|
146
|
+
|--------|-----------|-----------|
|
|
147
|
+
| Rotation | `number` (radians) | Quaternion (`x, y, z, w`) |
|
|
148
|
+
| Transform fields | 6 (`posX/Y`, `rot`, `prevPosX/Y`, `prevRot`) | 14 (+ Z, quaternion `x/y/z/w`) |
|
|
149
|
+
| Gravity | `{ x, y }` | `{ x, y, z }` |
|
|
150
|
+
| `cuboid()` | `cuboid(hx, hy)` | `cuboid(hx, hy, hz)` |
|
|
151
|
+
| `convexHull()` | Available | Not available |
|
|
152
|
+
| `cylinder()`/`cone()` | Not available | Available in Rapier 3D |
|
|
153
|
+
|
|
154
|
+
## PhysicsConfig2d
|
|
155
|
+
|
|
156
|
+
| Property | Type | Default | Description |
|
|
157
|
+
|----------|------|---------|-------------|
|
|
158
|
+
| `gravityX` | `number` | `0` | Gravity X component |
|
|
159
|
+
| `gravityY` | `number` | `-9.81` | Gravity Y component |
|
|
160
|
+
| `substeps` | `number` | `1` | Physics substeps per frame |
|
|
161
|
+
| `substepDt` | `number` | (derived) | `frameDt / substeps` |
|
|
162
|
+
|
|
163
|
+
## Collision Layers
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { CollisionLayers } from '@lagless/physics2d';
|
|
167
|
+
|
|
168
|
+
const layers = new CollisionLayers();
|
|
169
|
+
const PLAYER = layers.layer('player');
|
|
170
|
+
const GROUND = layers.layer('ground');
|
|
171
|
+
const PROJECTILE = layers.layer('projectile');
|
|
172
|
+
|
|
173
|
+
layers
|
|
174
|
+
.pair('player', 'ground')
|
|
175
|
+
.pair('player', 'projectile')
|
|
176
|
+
.selfPair('projectile');
|
|
177
|
+
|
|
178
|
+
// Use when creating colliders:
|
|
179
|
+
const groups = layers.groups('player');
|
|
180
|
+
worldManager.createBallCollider(0.5, body, groups, RAPIER.ActiveEvents.COLLISION_EVENTS);
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Max 16 named layers.
|
|
184
|
+
|
|
185
|
+
## Collision Events
|
|
186
|
+
|
|
187
|
+
Enable by passing `collisionLayers` to the runner constructor. Then inject `CollisionEvents2d` in your system:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
@ECSSystem()
|
|
191
|
+
class DamageSystem implements IECSSystem {
|
|
192
|
+
constructor(private readonly _events: CollisionEvents2d) {}
|
|
193
|
+
|
|
194
|
+
update(tick: number): void {
|
|
195
|
+
for (let i = 0; i < this._events.collisionEnterCount; i++) {
|
|
196
|
+
const entityA = this._events.collisionEnterEntityA(i);
|
|
197
|
+
const entityB = this._events.collisionEnterEntityB(i);
|
|
198
|
+
// handle collision...
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Event types: `collisionEnter/Exit`, `sensorEnter/Exit`, `contactForce` (with magnitude).
|
|
205
|
+
|
|
206
|
+
Events are ephemeral — cleared each tick, regenerated on rollback re-simulation. Zero-allocation SoA buffers.
|
|
207
|
+
|
|
208
|
+
## Snapshot/Rollback
|
|
209
|
+
|
|
210
|
+
`PhysicsSimulation2d` automatically maintains parallel snapshot histories for both ECS (ArrayBuffer) and Rapier (binary). On rollback, both are restored in sync. No manual intervention needed.
|
|
211
|
+
|
|
212
|
+
## Body Types
|
|
213
|
+
|
|
214
|
+
| Constant | Value | Description |
|
|
215
|
+
|----------|-------|-------------|
|
|
216
|
+
| `BodyType.DYNAMIC` | `0` | Physics-simulated |
|
|
217
|
+
| `BodyType.FIXED` | `1` | Static, immovable |
|
|
218
|
+
| `BodyType.KINEMATIC_POSITION` | `2` | ECS-driven position |
|
|
219
|
+
| `BodyType.KINEMATIC_VELOCITY` | `3` | ECS-driven velocity |
|
|
220
|
+
|
|
221
|
+
## API Reference
|
|
222
|
+
|
|
223
|
+
### PhysicsWorldManager2d
|
|
224
|
+
|
|
225
|
+
**Body factories:** `createDynamicBody()`, `createFixedBody()`, `createKinematicPositionBody()`, `createKinematicVelocityBody()`, `createBodyFromDesc(desc)`
|
|
226
|
+
|
|
227
|
+
**Collider factories:** `createBallCollider(r, parent?, groups?, events?)`, `createCuboidCollider(hx, hy, parent?, groups?, events?)`, `createCapsuleCollider(halfH, r, parent?, groups?, events?)`, `createConvexHullCollider(points, parent?, groups?, events?)`, `createTrimeshCollider(vertices, indices, parent?)`, `createColliderFromDesc(desc, parent?)`
|
|
228
|
+
|
|
229
|
+
**Accessors:** `getBody(handle)`, `getCollider(handle)`, `world`, `substeps`, `colliderEntityMap`, `rapier`
|
|
230
|
+
|
|
231
|
+
**Lifecycle:** `step()`, `takeSnapshot()`, `restoreSnapshot(data)`, `registerCollider(handle, entity)`, `unregisterCollider(handle)`, `enableCollisionEvents(events)`, `dispose()`
|
|
232
|
+
|
|
233
|
+
### PhysicsStepSync2d (static)
|
|
234
|
+
|
|
235
|
+
- `savePrevTransforms(filter, transform)` — copy current → prev fields
|
|
236
|
+
- `syncKinematicToRapier(filter, physicsRefs, transform, worldManager)` — ECS → Rapier for kinematic bodies
|
|
237
|
+
- `syncDynamicFromRapier(filter, physicsRefs, transform, worldManager)` — Rapier → ECS for dynamic bodies
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './lib/rapier-types-2d.js';
|
|
2
|
+
export * from './lib/physics-config-2d.js';
|
|
3
|
+
export * from './lib/collision-events-2d.js';
|
|
4
|
+
export * from './lib/physics-world-manager-2d.js';
|
|
5
|
+
export * from './lib/physics-step-sync-2d.js';
|
|
6
|
+
export * from './lib/physics-simulation-2d.js';
|
|
7
|
+
export * from './lib/physics-runner-2d.js';
|
|
8
|
+
export { BodyType, type BodyTypeValue, ColliderEntityMap, handleToIndex, CollisionLayers, CollisionEventsBase } from '@lagless/physics-shared';
|
|
9
|
+
export type { IPhysicsRefsComponent, IFilter, IPhysicsWorldManagerBase, IRapierEventQueue, IColliderSensorChecker } from '@lagless/physics-shared';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAE3C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC/I,YAAY,EAAE,qBAAqB,EAAE,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './lib/rapier-types-2d.js';
|
|
2
|
+
export * from './lib/physics-config-2d.js';
|
|
3
|
+
export * from './lib/collision-events-2d.js';
|
|
4
|
+
export * from './lib/physics-world-manager-2d.js';
|
|
5
|
+
export * from './lib/physics-step-sync-2d.js';
|
|
6
|
+
export * from './lib/physics-simulation-2d.js';
|
|
7
|
+
export * from './lib/physics-runner-2d.js';
|
|
8
|
+
export { BodyType, ColliderEntityMap, handleToIndex, CollisionLayers, CollisionEventsBase } from '@lagless/physics-shared';
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './lib/rapier-types-2d.js';\nexport * from './lib/physics-config-2d.js';\nexport * from './lib/collision-events-2d.js';\nexport * from './lib/physics-world-manager-2d.js';\nexport * from './lib/physics-step-sync-2d.js';\nexport * from './lib/physics-simulation-2d.js';\nexport * from './lib/physics-runner-2d.js';\n\nexport { BodyType, type BodyTypeValue, ColliderEntityMap, handleToIndex, CollisionLayers, CollisionEventsBase } from '@lagless/physics-shared';\nexport type { IPhysicsRefsComponent, IFilter, IPhysicsWorldManagerBase, IRapierEventQueue, IColliderSensorChecker } from '@lagless/physics-shared';\n"],"names":["BodyType","ColliderEntityMap","handleToIndex","CollisionLayers","CollisionEventsBase"],"rangeMappings":";;;;;;;","mappings":"AAAA,cAAc,2BAA2B;AACzC,cAAc,6BAA6B;AAC3C,cAAc,+BAA+B;AAC7C,cAAc,oCAAoC;AAClD,cAAc,gCAAgC;AAC9C,cAAc,iCAAiC;AAC/C,cAAc,6BAA6B;AAE3C,SAASA,QAAQ,EAAsBC,iBAAiB,EAAEC,aAAa,EAAEC,eAAe,EAAEC,mBAAmB,QAAQ,0BAA0B"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CollisionEventsBase } from '@lagless/physics-shared';
|
|
2
|
+
import type { RapierModule2d } from './rapier-types-2d.js';
|
|
3
|
+
export declare class CollisionEvents2d extends CollisionEventsBase {
|
|
4
|
+
constructor(rapier: RapierModule2d, initialCapacity?: number);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=collision-events-2d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collision-events-2d.d.ts","sourceRoot":"","sources":["../../src/lib/collision-events-2d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,qBAAa,iBAAkB,SAAQ,mBAAmB;gBAC5C,MAAM,EAAE,cAAc,EAAE,eAAe,CAAC,EAAE,MAAM;CAG7D"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CollisionEventsBase } from '@lagless/physics-shared';
|
|
2
|
+
export class CollisionEvents2d extends CollisionEventsBase {
|
|
3
|
+
constructor(rapier, initialCapacity){
|
|
4
|
+
super(rapier.EventQueue, initialCapacity);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=collision-events-2d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/collision-events-2d.ts"],"sourcesContent":["import { CollisionEventsBase } from '@lagless/physics-shared';\nimport type { RapierModule2d } from './rapier-types-2d.js';\n\nexport class CollisionEvents2d extends CollisionEventsBase {\n constructor(rapier: RapierModule2d, initialCapacity?: number) {\n super(rapier.EventQueue, initialCapacity);\n }\n}\n"],"names":["CollisionEventsBase","CollisionEvents2d","constructor","rapier","initialCapacity","EventQueue"],"rangeMappings":";;;;;","mappings":"AAAA,SAASA,mBAAmB,QAAQ,0BAA0B;AAG9D,OAAO,MAAMC,0BAA0BD;IACrCE,YAAYC,MAAsB,EAAEC,eAAwB,CAAE;QAC5D,KAAK,CAACD,OAAOE,UAAU,EAAED;IAC3B;AACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class PhysicsConfig2d {
|
|
2
|
+
readonly gravityX: number;
|
|
3
|
+
readonly gravityY: number;
|
|
4
|
+
readonly substeps: number;
|
|
5
|
+
/** Per-substep dt in seconds, derived from frameDt / substeps */
|
|
6
|
+
readonly substepDt: number;
|
|
7
|
+
constructor(options?: Partial<Pick<PhysicsConfig2d, 'gravityX' | 'gravityY' | 'substeps'>>, frameDt?: number);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=physics-config-2d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-config-2d.d.ts","sourceRoot":"","sources":["../../src/lib/physics-config-2d.ts"],"names":[],"mappings":"AAAA,qBAAa,eAAe;IAC1B,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,iEAAiE;IACjE,SAAgB,SAAS,EAAE,MAAM,CAAC;gBAGhC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC,EAC9E,OAAO,GAAE,MAAe;CAO3B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class PhysicsConfig2d {
|
|
2
|
+
constructor(options, frameDt = 1 / 60){
|
|
3
|
+
var _options_gravityX;
|
|
4
|
+
this.gravityX = (_options_gravityX = options == null ? void 0 : options.gravityX) != null ? _options_gravityX : 0;
|
|
5
|
+
var _options_gravityY;
|
|
6
|
+
this.gravityY = (_options_gravityY = options == null ? void 0 : options.gravityY) != null ? _options_gravityY : -9.81;
|
|
7
|
+
var _options_substeps;
|
|
8
|
+
this.substeps = (_options_substeps = options == null ? void 0 : options.substeps) != null ? _options_substeps : 1;
|
|
9
|
+
this.substepDt = frameDt / this.substeps;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=physics-config-2d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/physics-config-2d.ts"],"sourcesContent":["export class PhysicsConfig2d {\n public readonly gravityX: number;\n public readonly gravityY: number;\n public readonly substeps: number;\n /** Per-substep dt in seconds, derived from frameDt / substeps */\n public readonly substepDt: number;\n\n constructor(\n options?: Partial<Pick<PhysicsConfig2d, 'gravityX' | 'gravityY' | 'substeps'>>,\n frameDt: number = 1 / 60,\n ) {\n this.gravityX = options?.gravityX ?? 0;\n this.gravityY = options?.gravityY ?? -9.81;\n this.substeps = options?.substeps ?? 1;\n this.substepDt = frameDt / this.substeps;\n }\n}\n"],"names":["PhysicsConfig2d","constructor","options","frameDt","gravityX","gravityY","substeps","substepDt"],"rangeMappings":";;;;;;;;;;","mappings":"AAAA,OAAO,MAAMA;IAOXC,YACEC,OAA8E,EAC9EC,UAAkB,IAAI,EAAE,CACxB;YACgBD;QAAhB,IAAI,CAACE,QAAQ,GAAGF,CAAAA,oBAAAA,2BAAAA,QAASE,QAAQ,YAAjBF,oBAAqB;YACrBA;QAAhB,IAAI,CAACG,QAAQ,GAAGH,CAAAA,oBAAAA,2BAAAA,QAASG,QAAQ,YAAjBH,oBAAqB,CAAC;YACtBA;QAAhB,IAAI,CAACI,QAAQ,GAAGJ,CAAAA,oBAAAA,2BAAAA,QAASI,QAAQ,YAAjBJ,oBAAqB;QACrC,IAAI,CAACK,SAAS,GAAGJ,UAAU,IAAI,CAACG,QAAQ;IAC1C;AACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AbstractInputProvider, ECSConfig, ECSRunner, ECSDeps, IECSSystemConstructor } from '@lagless/core';
|
|
2
|
+
import { ISignalConstructor } from '@lagless/core';
|
|
3
|
+
import { CollisionLayers } from '@lagless/physics-shared';
|
|
4
|
+
import { CollisionEvents2d } from './collision-events-2d.js';
|
|
5
|
+
import { PhysicsConfig2d } from './physics-config-2d.js';
|
|
6
|
+
import { PhysicsSimulation2d } from './physics-simulation-2d.js';
|
|
7
|
+
import { PhysicsWorldManager2d } from './physics-world-manager-2d.js';
|
|
8
|
+
import { RapierModule2d } from './rapier-types-2d.js';
|
|
9
|
+
export declare abstract class PhysicsRunner2d extends ECSRunner {
|
|
10
|
+
readonly PhysicsWorldManager: PhysicsWorldManager2d;
|
|
11
|
+
readonly PhysicsConfig: PhysicsConfig2d;
|
|
12
|
+
readonly CollisionEvents: CollisionEvents2d;
|
|
13
|
+
readonly Simulation: PhysicsSimulation2d;
|
|
14
|
+
protected constructor(Config: ECSConfig, InputProviderInstance: AbstractInputProvider, Systems: Array<IECSSystemConstructor>, Signals: Array<ISignalConstructor>, Deps: ECSDeps, rapier: RapierModule2d, physicsConfig?: PhysicsConfig2d, collisionLayers?: CollisionLayers, extraRegistrations?: Array<[unknown, unknown]>);
|
|
15
|
+
dispose(): void;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=physics-runner-2d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-runner-2d.d.ts","sourceRoot":"","sources":["../../src/lib/physics-runner-2d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC5G,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,8BAAsB,eAAgB,SAAQ,SAAS;IACrD,SAAgB,mBAAmB,EAAE,qBAAqB,CAAC;IAC3D,SAAgB,aAAa,EAAE,eAAe,CAAC;IAC/C,SAAgB,eAAe,EAAE,iBAAiB,CAAC;IACnD,SAAyB,UAAU,EAAE,mBAAmB,CAAC;IAEzD,SAAS,aACP,MAAM,EAAE,SAAS,EACjB,qBAAqB,EAAE,qBAAqB,EAC5C,OAAO,EAAE,KAAK,CAAC,qBAAqB,CAAC,EACrC,OAAO,EAAE,KAAK,CAAC,kBAAkB,CAAC,EAClC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,cAAc,EACtB,aAAa,CAAC,EAAE,eAAe,EAC/B,eAAe,CAAC,EAAE,eAAe,EACjC,kBAAkB,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IA0BhC,OAAO,IAAI,IAAI;CAIhC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ECSRunner } from '@lagless/core';
|
|
2
|
+
import { CollisionLayers } from '@lagless/physics-shared';
|
|
3
|
+
import { CollisionEvents2d } from './collision-events-2d.js';
|
|
4
|
+
import { PhysicsConfig2d } from './physics-config-2d.js';
|
|
5
|
+
import { PhysicsSimulation2d } from './physics-simulation-2d.js';
|
|
6
|
+
import { PhysicsWorldManager2d } from './physics-world-manager-2d.js';
|
|
7
|
+
export class PhysicsRunner2d extends ECSRunner {
|
|
8
|
+
dispose() {
|
|
9
|
+
super.dispose();
|
|
10
|
+
this.PhysicsWorldManager.dispose();
|
|
11
|
+
}
|
|
12
|
+
constructor(Config, InputProviderInstance, Systems, Signals, Deps, rapier, physicsConfig, collisionLayers, extraRegistrations){
|
|
13
|
+
const config = physicsConfig != null ? physicsConfig : new PhysicsConfig2d();
|
|
14
|
+
const worldManager = new PhysicsWorldManager2d(rapier, config, Config.frameLength);
|
|
15
|
+
const simulation = new PhysicsSimulation2d(Config, Deps, InputProviderInstance, worldManager);
|
|
16
|
+
const extraRegs = [
|
|
17
|
+
[
|
|
18
|
+
PhysicsWorldManager2d,
|
|
19
|
+
worldManager
|
|
20
|
+
],
|
|
21
|
+
[
|
|
22
|
+
PhysicsConfig2d,
|
|
23
|
+
config
|
|
24
|
+
],
|
|
25
|
+
[
|
|
26
|
+
CollisionEvents2d,
|
|
27
|
+
worldManager.collisionEvents
|
|
28
|
+
]
|
|
29
|
+
];
|
|
30
|
+
if (collisionLayers) {
|
|
31
|
+
extraRegs.push([
|
|
32
|
+
CollisionLayers,
|
|
33
|
+
collisionLayers
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
if (extraRegistrations) {
|
|
37
|
+
extraRegs.push(...extraRegistrations);
|
|
38
|
+
}
|
|
39
|
+
super(Config, InputProviderInstance, Systems, Signals, Deps, simulation, extraRegs);
|
|
40
|
+
this.PhysicsWorldManager = worldManager;
|
|
41
|
+
this.PhysicsConfig = config;
|
|
42
|
+
this.Simulation = simulation;
|
|
43
|
+
this.CollisionEvents = worldManager.collisionEvents;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=physics-runner-2d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/physics-runner-2d.ts"],"sourcesContent":["import { AbstractInputProvider, ECSConfig, ECSRunner, ECSDeps, IECSSystemConstructor } from '@lagless/core';\nimport { ISignalConstructor } from '@lagless/core';\nimport { CollisionLayers } from '@lagless/physics-shared';\nimport { CollisionEvents2d } from './collision-events-2d.js';\nimport { PhysicsConfig2d } from './physics-config-2d.js';\nimport { PhysicsSimulation2d } from './physics-simulation-2d.js';\nimport { PhysicsWorldManager2d } from './physics-world-manager-2d.js';\nimport { RapierModule2d } from './rapier-types-2d.js';\n\nexport abstract class PhysicsRunner2d extends ECSRunner {\n public readonly PhysicsWorldManager: PhysicsWorldManager2d;\n public readonly PhysicsConfig: PhysicsConfig2d;\n public readonly CollisionEvents: CollisionEvents2d;\n public override readonly Simulation: PhysicsSimulation2d;\n\n protected constructor(\n Config: ECSConfig,\n InputProviderInstance: AbstractInputProvider,\n Systems: Array<IECSSystemConstructor>,\n Signals: Array<ISignalConstructor>,\n Deps: ECSDeps,\n rapier: RapierModule2d,\n physicsConfig?: PhysicsConfig2d,\n collisionLayers?: CollisionLayers,\n extraRegistrations?: Array<[unknown, unknown]>,\n ) {\n const config = physicsConfig ?? new PhysicsConfig2d();\n const worldManager = new PhysicsWorldManager2d(rapier, config, Config.frameLength);\n const simulation = new PhysicsSimulation2d(Config, Deps, InputProviderInstance, worldManager);\n\n const extraRegs: Array<[unknown, unknown]> = [\n [PhysicsWorldManager2d, worldManager],\n [PhysicsConfig2d, config],\n [CollisionEvents2d, worldManager.collisionEvents],\n ];\n if (collisionLayers) {\n extraRegs.push([CollisionLayers, collisionLayers]);\n }\n if (extraRegistrations) {\n extraRegs.push(...extraRegistrations);\n }\n\n super(Config, InputProviderInstance, Systems, Signals, Deps, simulation, extraRegs);\n\n this.PhysicsWorldManager = worldManager;\n this.PhysicsConfig = config;\n this.Simulation = simulation;\n this.CollisionEvents = worldManager.collisionEvents;\n }\n\n public override dispose(): void {\n super.dispose();\n this.PhysicsWorldManager.dispose();\n }\n}\n"],"names":["ECSRunner","CollisionLayers","CollisionEvents2d","PhysicsConfig2d","PhysicsSimulation2d","PhysicsWorldManager2d","PhysicsRunner2d","dispose","PhysicsWorldManager","Config","InputProviderInstance","Systems","Signals","Deps","rapier","physicsConfig","collisionLayers","extraRegistrations","config","worldManager","frameLength","simulation","extraRegs","collisionEvents","push","PhysicsConfig","Simulation","CollisionEvents"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAA2CA,SAAS,QAAwC,gBAAgB;AAE5G,SAASC,eAAe,QAAQ,0BAA0B;AAC1D,SAASC,iBAAiB,QAAQ,2BAA2B;AAC7D,SAASC,eAAe,QAAQ,yBAAyB;AACzD,SAASC,mBAAmB,QAAQ,6BAA6B;AACjE,SAASC,qBAAqB,QAAQ,gCAAgC;AAGtE,OAAO,MAAeC,wBAAwBN;IAyC5BO,UAAgB;QAC9B,KAAK,CAACA;QACN,IAAI,CAACC,mBAAmB,CAACD,OAAO;IAClC;IAtCA,YACEE,MAAiB,EACjBC,qBAA4C,EAC5CC,OAAqC,EACrCC,OAAkC,EAClCC,IAAa,EACbC,MAAsB,EACtBC,aAA+B,EAC/BC,eAAiC,EACjCC,kBAA8C,CAC9C;QACA,MAAMC,SAASH,wBAAAA,gBAAiB,IAAIZ;QACpC,MAAMgB,eAAe,IAAId,sBAAsBS,QAAQI,QAAQT,OAAOW,WAAW;QACjF,MAAMC,aAAa,IAAIjB,oBAAoBK,QAAQI,MAAMH,uBAAuBS;QAEhF,MAAMG,YAAuC;YAC3C;gBAACjB;gBAAuBc;aAAa;YACrC;gBAAChB;gBAAiBe;aAAO;YACzB;gBAAChB;gBAAmBiB,aAAaI,eAAe;aAAC;SAClD;QACD,IAAIP,iBAAiB;YACnBM,UAAUE,IAAI,CAAC;gBAACvB;gBAAiBe;aAAgB;QACnD;QACA,IAAIC,oBAAoB;YACtBK,UAAUE,IAAI,IAAIP;QACpB;QAEA,KAAK,CAACR,QAAQC,uBAAuBC,SAASC,SAASC,MAAMQ,YAAYC;QAEzE,IAAI,CAACd,mBAAmB,GAAGW;QAC3B,IAAI,CAACM,aAAa,GAAGP;QACrB,IAAI,CAACQ,UAAU,GAAGL;QAClB,IAAI,CAACM,eAAe,GAAGR,aAAaI,eAAe;IACrD;AAMF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ECSConfig, AbstractInputProvider, ECSDeps } from '@lagless/core';
|
|
2
|
+
import { PhysicsSimulationBase } from '@lagless/physics-shared';
|
|
3
|
+
import { PhysicsWorldManager2d } from './physics-world-manager-2d.js';
|
|
4
|
+
export declare class PhysicsSimulation2d extends PhysicsSimulationBase {
|
|
5
|
+
constructor(config: ECSConfig, deps: ECSDeps, inputProvider: AbstractInputProvider, physicsWorldManager: PhysicsWorldManager2d);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=physics-simulation-2d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-simulation-2d.d.ts","sourceRoot":"","sources":["../../src/lib/physics-simulation-2d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,qBAAa,mBAAoB,SAAQ,qBAAqB;gBAE1D,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,OAAO,EACb,aAAa,EAAE,qBAAqB,EACpC,mBAAmB,EAAE,qBAAqB;CAI7C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PhysicsSimulationBase } from '@lagless/physics-shared';
|
|
2
|
+
export class PhysicsSimulation2d extends PhysicsSimulationBase {
|
|
3
|
+
constructor(config, deps, inputProvider, physicsWorldManager){
|
|
4
|
+
super(config, deps, inputProvider, physicsWorldManager);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=physics-simulation-2d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/physics-simulation-2d.ts"],"sourcesContent":["import { ECSConfig, AbstractInputProvider, ECSDeps } from '@lagless/core';\nimport { PhysicsSimulationBase } from '@lagless/physics-shared';\nimport { PhysicsWorldManager2d } from './physics-world-manager-2d.js';\n\nexport class PhysicsSimulation2d extends PhysicsSimulationBase {\n constructor(\n config: ECSConfig,\n deps: ECSDeps,\n inputProvider: AbstractInputProvider,\n physicsWorldManager: PhysicsWorldManager2d,\n ) {\n super(config, deps, inputProvider, physicsWorldManager);\n }\n}\n"],"names":["PhysicsSimulationBase","PhysicsSimulation2d","constructor","config","deps","inputProvider","physicsWorldManager"],"rangeMappings":";;;;;","mappings":"AACA,SAASA,qBAAqB,QAAQ,0BAA0B;AAGhE,OAAO,MAAMC,4BAA4BD;IACvCE,YACEC,MAAiB,EACjBC,IAAa,EACbC,aAAoC,EACpCC,mBAA0C,CAC1C;QACA,KAAK,CAACH,QAAQC,MAAMC,eAAeC;IACrC;AACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { PhysicsWorldManager2d } from './physics-world-manager-2d.js';
|
|
2
|
+
export type { IPhysicsRefsComponent, IFilter } from '@lagless/physics-shared';
|
|
3
|
+
export { BodyType as BodyType2d } from '@lagless/physics-shared';
|
|
4
|
+
export interface ITransform2dComponent {
|
|
5
|
+
positionX: {
|
|
6
|
+
get(entity: number): number;
|
|
7
|
+
set(entity: number, v: number): void;
|
|
8
|
+
};
|
|
9
|
+
positionY: {
|
|
10
|
+
get(entity: number): number;
|
|
11
|
+
set(entity: number, v: number): void;
|
|
12
|
+
};
|
|
13
|
+
rotation: {
|
|
14
|
+
get(entity: number): number;
|
|
15
|
+
set(entity: number, v: number): void;
|
|
16
|
+
};
|
|
17
|
+
prevPositionX: {
|
|
18
|
+
get(entity: number): number;
|
|
19
|
+
set(entity: number, v: number): void;
|
|
20
|
+
};
|
|
21
|
+
prevPositionY: {
|
|
22
|
+
get(entity: number): number;
|
|
23
|
+
set(entity: number, v: number): void;
|
|
24
|
+
};
|
|
25
|
+
prevRotation: {
|
|
26
|
+
get(entity: number): number;
|
|
27
|
+
set(entity: number, v: number): void;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export declare class PhysicsStepSync2d {
|
|
31
|
+
static savePrevTransforms(filter: import('@lagless/physics-shared').IFilter, transform: ITransform2dComponent): void;
|
|
32
|
+
static syncKinematicToRapier(filter: import('@lagless/physics-shared').IFilter, physicsRefs: import('@lagless/physics-shared').IPhysicsRefsComponent, transform: ITransform2dComponent, worldManager: PhysicsWorldManager2d): void;
|
|
33
|
+
static syncDynamicFromRapier(filter: import('@lagless/physics-shared').IFilter, physicsRefs: import('@lagless/physics-shared').IPhysicsRefsComponent, transform: ITransform2dComponent, worldManager: PhysicsWorldManager2d): void;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=physics-step-sync-2d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-step-sync-2d.d.ts","sourceRoot":"","sources":["../../src/lib/physics-step-sync-2d.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,YAAY,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE;QAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACjF,SAAS,EAAE;QAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACjF,QAAQ,EAAE;QAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChF,aAAa,EAAE;QAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACrF,aAAa,EAAE;QAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACrF,YAAY,EAAE;QAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CACrF;AAID,qBAAa,iBAAiB;IAC5B,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,OAAO,yBAAyB,EAAE,OAAO,EAAE,SAAS,EAAE,qBAAqB,GAAG,IAAI;IASpH,MAAM,CAAC,qBAAqB,CAC1B,MAAM,EAAE,OAAO,yBAAyB,EAAE,OAAO,EACjD,WAAW,EAAE,OAAO,yBAAyB,EAAE,qBAAqB,EACpE,SAAS,EAAE,qBAAqB,EAChC,YAAY,EAAE,qBAAqB,GAClC,IAAI;IAcP,MAAM,CAAC,qBAAqB,CAC1B,MAAM,EAAE,OAAO,yBAAyB,EAAE,OAAO,EACjD,WAAW,EAAE,OAAO,yBAAyB,EAAE,qBAAqB,EACpE,SAAS,EAAE,qBAAqB,EAChC,YAAY,EAAE,qBAAqB,GAClC,IAAI;CAeR"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BodyType } from '@lagless/physics-shared';
|
|
2
|
+
export { BodyType as BodyType2d } from '@lagless/physics-shared';
|
|
3
|
+
const _vec2 = {
|
|
4
|
+
x: 0,
|
|
5
|
+
y: 0
|
|
6
|
+
};
|
|
7
|
+
export class PhysicsStepSync2d {
|
|
8
|
+
static savePrevTransforms(filter, transform) {
|
|
9
|
+
for(let i = 0; i < filter.length; i++){
|
|
10
|
+
const e = filter.entities(i);
|
|
11
|
+
transform.prevPositionX.set(e, transform.positionX.get(e));
|
|
12
|
+
transform.prevPositionY.set(e, transform.positionY.get(e));
|
|
13
|
+
transform.prevRotation.set(e, transform.rotation.get(e));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
static syncKinematicToRapier(filter, physicsRefs, transform, worldManager) {
|
|
17
|
+
for(let i = 0; i < filter.length; i++){
|
|
18
|
+
const e = filter.entities(i);
|
|
19
|
+
const type = physicsRefs.bodyType.get(e);
|
|
20
|
+
if (type !== BodyType.KINEMATIC_POSITION && type !== BodyType.KINEMATIC_VELOCITY) continue;
|
|
21
|
+
const body = worldManager.getBody(physicsRefs.bodyHandle.get(e));
|
|
22
|
+
_vec2.x = transform.positionX.get(e);
|
|
23
|
+
_vec2.y = transform.positionY.get(e);
|
|
24
|
+
body.setNextKinematicTranslation(_vec2);
|
|
25
|
+
body.setNextKinematicRotation(transform.rotation.get(e));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
static syncDynamicFromRapier(filter, physicsRefs, transform, worldManager) {
|
|
29
|
+
for(let i = 0; i < filter.length; i++){
|
|
30
|
+
const e = filter.entities(i);
|
|
31
|
+
const type = physicsRefs.bodyType.get(e);
|
|
32
|
+
if (type !== BodyType.DYNAMIC) continue;
|
|
33
|
+
const body = worldManager.getBody(physicsRefs.bodyHandle.get(e));
|
|
34
|
+
const pos = body.translation();
|
|
35
|
+
const rot = body.rotation();
|
|
36
|
+
transform.positionX.set(e, pos.x);
|
|
37
|
+
transform.positionY.set(e, pos.y);
|
|
38
|
+
transform.rotation.set(e, rot);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=physics-step-sync-2d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/physics-step-sync-2d.ts"],"sourcesContent":["import { BodyType } from '@lagless/physics-shared';\nimport { PhysicsWorldManager2d } from './physics-world-manager-2d.js';\n\nexport type { IPhysicsRefsComponent, IFilter } from '@lagless/physics-shared';\nexport { BodyType as BodyType2d } from '@lagless/physics-shared';\n\nexport interface ITransform2dComponent {\n positionX: { get(entity: number): number; set(entity: number, v: number): void };\n positionY: { get(entity: number): number; set(entity: number, v: number): void };\n rotation: { get(entity: number): number; set(entity: number, v: number): void };\n prevPositionX: { get(entity: number): number; set(entity: number, v: number): void };\n prevPositionY: { get(entity: number): number; set(entity: number, v: number): void };\n prevRotation: { get(entity: number): number; set(entity: number, v: number): void };\n}\n\nconst _vec2 = { x: 0, y: 0 };\n\nexport class PhysicsStepSync2d {\n static savePrevTransforms(filter: import('@lagless/physics-shared').IFilter, transform: ITransform2dComponent): void {\n for (let i = 0; i < filter.length; i++) {\n const e = filter.entities(i);\n transform.prevPositionX.set(e, transform.positionX.get(e));\n transform.prevPositionY.set(e, transform.positionY.get(e));\n transform.prevRotation.set(e, transform.rotation.get(e));\n }\n }\n\n static syncKinematicToRapier(\n filter: import('@lagless/physics-shared').IFilter,\n physicsRefs: import('@lagless/physics-shared').IPhysicsRefsComponent,\n transform: ITransform2dComponent,\n worldManager: PhysicsWorldManager2d,\n ): void {\n for (let i = 0; i < filter.length; i++) {\n const e = filter.entities(i);\n const type = physicsRefs.bodyType.get(e);\n if (type !== BodyType.KINEMATIC_POSITION && type !== BodyType.KINEMATIC_VELOCITY) continue;\n\n const body = worldManager.getBody(physicsRefs.bodyHandle.get(e));\n _vec2.x = transform.positionX.get(e);\n _vec2.y = transform.positionY.get(e);\n body.setNextKinematicTranslation(_vec2);\n body.setNextKinematicRotation(transform.rotation.get(e));\n }\n }\n\n static syncDynamicFromRapier(\n filter: import('@lagless/physics-shared').IFilter,\n physicsRefs: import('@lagless/physics-shared').IPhysicsRefsComponent,\n transform: ITransform2dComponent,\n worldManager: PhysicsWorldManager2d,\n ): void {\n for (let i = 0; i < filter.length; i++) {\n const e = filter.entities(i);\n const type = physicsRefs.bodyType.get(e);\n if (type !== BodyType.DYNAMIC) continue;\n\n const body = worldManager.getBody(physicsRefs.bodyHandle.get(e));\n const pos = body.translation();\n const rot = body.rotation();\n\n transform.positionX.set(e, pos.x);\n transform.positionY.set(e, pos.y);\n transform.rotation.set(e, rot);\n }\n }\n}\n"],"names":["BodyType","BodyType2d","_vec2","x","y","PhysicsStepSync2d","savePrevTransforms","filter","transform","i","length","e","entities","prevPositionX","set","positionX","get","prevPositionY","positionY","prevRotation","rotation","syncKinematicToRapier","physicsRefs","worldManager","type","bodyType","KINEMATIC_POSITION","KINEMATIC_VELOCITY","body","getBody","bodyHandle","setNextKinematicTranslation","setNextKinematicRotation","syncDynamicFromRapier","DYNAMIC","pos","translation","rot"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,QAAQ,QAAQ,0BAA0B;AAInD,SAASA,YAAYC,UAAU,QAAQ,0BAA0B;AAWjE,MAAMC,QAAQ;IAAEC,GAAG;IAAGC,GAAG;AAAE;AAE3B,OAAO,MAAMC;IACX,OAAOC,mBAAmBC,MAAiD,EAAEC,SAAgC,EAAQ;QACnH,IAAK,IAAIC,IAAI,GAAGA,IAAIF,OAAOG,MAAM,EAAED,IAAK;YACtC,MAAME,IAAIJ,OAAOK,QAAQ,CAACH;YAC1BD,UAAUK,aAAa,CAACC,GAAG,CAACH,GAAGH,UAAUO,SAAS,CAACC,GAAG,CAACL;YACvDH,UAAUS,aAAa,CAACH,GAAG,CAACH,GAAGH,UAAUU,SAAS,CAACF,GAAG,CAACL;YACvDH,UAAUW,YAAY,CAACL,GAAG,CAACH,GAAGH,UAAUY,QAAQ,CAACJ,GAAG,CAACL;QACvD;IACF;IAEA,OAAOU,sBACLd,MAAiD,EACjDe,WAAoE,EACpEd,SAAgC,EAChCe,YAAmC,EAC7B;QACN,IAAK,IAAId,IAAI,GAAGA,IAAIF,OAAOG,MAAM,EAAED,IAAK;YACtC,MAAME,IAAIJ,OAAOK,QAAQ,CAACH;YAC1B,MAAMe,OAAOF,YAAYG,QAAQ,CAACT,GAAG,CAACL;YACtC,IAAIa,SAASxB,SAAS0B,kBAAkB,IAAIF,SAASxB,SAAS2B,kBAAkB,EAAE;YAElF,MAAMC,OAAOL,aAAaM,OAAO,CAACP,YAAYQ,UAAU,CAACd,GAAG,CAACL;YAC7DT,MAAMC,CAAC,GAAGK,UAAUO,SAAS,CAACC,GAAG,CAACL;YAClCT,MAAME,CAAC,GAAGI,UAAUU,SAAS,CAACF,GAAG,CAACL;YAClCiB,KAAKG,2BAA2B,CAAC7B;YACjC0B,KAAKI,wBAAwB,CAACxB,UAAUY,QAAQ,CAACJ,GAAG,CAACL;QACvD;IACF;IAEA,OAAOsB,sBACL1B,MAAiD,EACjDe,WAAoE,EACpEd,SAAgC,EAChCe,YAAmC,EAC7B;QACN,IAAK,IAAId,IAAI,GAAGA,IAAIF,OAAOG,MAAM,EAAED,IAAK;YACtC,MAAME,IAAIJ,OAAOK,QAAQ,CAACH;YAC1B,MAAMe,OAAOF,YAAYG,QAAQ,CAACT,GAAG,CAACL;YACtC,IAAIa,SAASxB,SAASkC,OAAO,EAAE;YAE/B,MAAMN,OAAOL,aAAaM,OAAO,CAACP,YAAYQ,UAAU,CAACd,GAAG,CAACL;YAC7D,MAAMwB,MAAMP,KAAKQ,WAAW;YAC5B,MAAMC,MAAMT,KAAKR,QAAQ;YAEzBZ,UAAUO,SAAS,CAACD,GAAG,CAACH,GAAGwB,IAAIhC,CAAC;YAChCK,UAAUU,SAAS,CAACJ,GAAG,CAACH,GAAGwB,IAAI/B,CAAC;YAChCI,UAAUY,QAAQ,CAACN,GAAG,CAACH,GAAG0B;QAC5B;IACF;AACF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ColliderEntityMap } from '@lagless/physics-shared';
|
|
2
|
+
import { CollisionEvents2d } from './collision-events-2d.js';
|
|
3
|
+
import { PhysicsConfig2d } from './physics-config-2d.js';
|
|
4
|
+
import { RapierCollider2d, RapierColliderDesc2d, RapierModule2d, RapierRigidBody2d, RapierRigidBodyDesc2d, RapierWorld2d } from './rapier-types-2d.js';
|
|
5
|
+
export declare class PhysicsWorldManager2d {
|
|
6
|
+
private readonly _rapier;
|
|
7
|
+
private readonly _config;
|
|
8
|
+
private _world;
|
|
9
|
+
private readonly _substeps;
|
|
10
|
+
private readonly _substepDt;
|
|
11
|
+
private readonly _collisionEvents;
|
|
12
|
+
private readonly _colliderEntityMap;
|
|
13
|
+
get world(): RapierWorld2d;
|
|
14
|
+
get substeps(): number;
|
|
15
|
+
get colliderEntityMap(): ColliderEntityMap;
|
|
16
|
+
get collisionEvents(): CollisionEvents2d;
|
|
17
|
+
constructor(_rapier: RapierModule2d, _config: PhysicsConfig2d, frameLengthMs: number);
|
|
18
|
+
/**
|
|
19
|
+
* Step the physics world for one ECS frame.
|
|
20
|
+
* Executes `substeps` Rapier steps, each with a fixed dt derived from frameLength / substeps.
|
|
21
|
+
* When collision events are enabled, drains the event queue after all substeps.
|
|
22
|
+
*/
|
|
23
|
+
step(): void;
|
|
24
|
+
takeSnapshot(): Uint8Array;
|
|
25
|
+
restoreSnapshot(data: Uint8Array): void;
|
|
26
|
+
registerCollider(colliderHandle: number, entity: number): void;
|
|
27
|
+
unregisterCollider(colliderHandle: number): void;
|
|
28
|
+
createDynamicBody(): RapierRigidBody2d;
|
|
29
|
+
createFixedBody(): RapierRigidBody2d;
|
|
30
|
+
createKinematicPositionBody(): RapierRigidBody2d;
|
|
31
|
+
createKinematicVelocityBody(): RapierRigidBody2d;
|
|
32
|
+
createBodyFromDesc(desc: RapierRigidBodyDesc2d): RapierRigidBody2d;
|
|
33
|
+
createBallCollider(radius: number, parent?: RapierRigidBody2d, groups?: number, activeEvents?: number): RapierCollider2d;
|
|
34
|
+
createCuboidCollider(hx: number, hy: number, parent?: RapierRigidBody2d, groups?: number, activeEvents?: number): RapierCollider2d;
|
|
35
|
+
createCapsuleCollider(halfHeight: number, radius: number, parent?: RapierRigidBody2d, groups?: number, activeEvents?: number): RapierCollider2d;
|
|
36
|
+
createConvexHullCollider(points: Float32Array, parent?: RapierRigidBody2d, groups?: number, activeEvents?: number): RapierCollider2d | null;
|
|
37
|
+
createTrimeshCollider(vertices: Float32Array, indices: Uint32Array, parent?: RapierRigidBody2d): RapierCollider2d;
|
|
38
|
+
createColliderFromDesc(desc: RapierColliderDesc2d, parent?: RapierRigidBody2d): RapierCollider2d;
|
|
39
|
+
getBody(handle: number): RapierRigidBody2d;
|
|
40
|
+
getCollider(handle: number): RapierCollider2d;
|
|
41
|
+
removeBody(handle: number): void;
|
|
42
|
+
removeCollider(handle: number, wakeUp?: boolean): void;
|
|
43
|
+
get rapier(): RapierModule2d;
|
|
44
|
+
dispose(): void;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=physics-world-manager-2d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physics-world-manager-2d.d.ts","sourceRoot":"","sources":["../../src/lib/physics-world-manager-2d.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EAEpB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACd,MAAM,sBAAsB,CAAC;AAI9B,qBAAa,qBAAqB;IAwB9B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAxB1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoB;IACrD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;IAE9D,IAAW,KAAK,IAAI,aAAa,CAEhC;IAED,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAED,IAAW,iBAAiB,IAAI,iBAAiB,CAEhD;IAED,IAAW,eAAe,IAAI,iBAAiB,CAE9C;gBAGkB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,eAAe,EACzC,aAAa,EAAE,MAAM;IAavB;;;;OAIG;IACI,IAAI,IAAI,IAAI;IAQZ,YAAY,IAAI,UAAU;IAI1B,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAmBvC,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAI9D,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAKhD,iBAAiB,IAAI,iBAAiB;IAKtC,eAAe,IAAI,iBAAiB;IAKpC,2BAA2B,IAAI,iBAAiB;IAKhD,2BAA2B,IAAI,iBAAiB;IAKhD,kBAAkB,CAAC,IAAI,EAAE,qBAAqB,GAAG,iBAAiB;IAKlE,kBAAkB,CACvB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,gBAAgB;IAOZ,oBAAoB,CACzB,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,gBAAgB;IAOZ,qBAAqB,CAC1B,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAClC,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,gBAAgB;IAOZ,wBAAwB,CAC7B,MAAM,EAAE,YAAY,EACpB,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,gBAAgB,GAAG,IAAI;IAQnB,qBAAqB,CAC1B,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,WAAW,EACpB,MAAM,CAAC,EAAE,iBAAiB,GACzB,gBAAgB;IAKZ,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,iBAAiB,GAAG,gBAAgB;IAKhG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB;IAI1C,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAK7C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKhC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO,GAAG,IAAI;IAM1D,IAAW,MAAM,IAAI,cAAc,CAElC;IAEM,OAAO,IAAI,IAAI;CAIvB"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { createLogger } from '@lagless/misc';
|
|
2
|
+
import { ColliderEntityMap } from '@lagless/physics-shared';
|
|
3
|
+
import { CollisionEvents2d } from './collision-events-2d.js';
|
|
4
|
+
const log = createLogger('PhysicsWorldManager2d');
|
|
5
|
+
export class PhysicsWorldManager2d {
|
|
6
|
+
get world() {
|
|
7
|
+
return this._world;
|
|
8
|
+
}
|
|
9
|
+
get substeps() {
|
|
10
|
+
return this._substeps;
|
|
11
|
+
}
|
|
12
|
+
get colliderEntityMap() {
|
|
13
|
+
return this._colliderEntityMap;
|
|
14
|
+
}
|
|
15
|
+
get collisionEvents() {
|
|
16
|
+
return this._collisionEvents;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Step the physics world for one ECS frame.
|
|
20
|
+
* Executes `substeps` Rapier steps, each with a fixed dt derived from frameLength / substeps.
|
|
21
|
+
* When collision events are enabled, drains the event queue after all substeps.
|
|
22
|
+
*/ step() {
|
|
23
|
+
const eq = this._collisionEvents.eventQueue;
|
|
24
|
+
for(let i = 0; i < this._substeps; i++){
|
|
25
|
+
this._world.step(eq);
|
|
26
|
+
}
|
|
27
|
+
this._collisionEvents.drain(this._colliderEntityMap, this._world);
|
|
28
|
+
}
|
|
29
|
+
takeSnapshot() {
|
|
30
|
+
return this._world.takeSnapshot();
|
|
31
|
+
}
|
|
32
|
+
restoreSnapshot(data) {
|
|
33
|
+
this._world.free();
|
|
34
|
+
const restored = this._rapier.World.restoreSnapshot(data);
|
|
35
|
+
if (!restored) {
|
|
36
|
+
log.warn('Failed to restore Rapier snapshot, recreating world');
|
|
37
|
+
this._world = new this._rapier.World({
|
|
38
|
+
x: this._config.gravityX,
|
|
39
|
+
y: this._config.gravityY
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this._world = restored;
|
|
44
|
+
// CRITICAL: QueryPipeline is NOT included in the Rapier snapshot format.
|
|
45
|
+
// After restoreSnapshot(), the world has a fresh empty QueryPipeline.
|
|
46
|
+
// Any scene queries (ray casts, shape casts) will return wrong results until rebuilt.
|
|
47
|
+
this._world.updateSceneQueries();
|
|
48
|
+
}
|
|
49
|
+
// Entity-collider mapping
|
|
50
|
+
registerCollider(colliderHandle, entity) {
|
|
51
|
+
this._colliderEntityMap.set(colliderHandle, entity);
|
|
52
|
+
}
|
|
53
|
+
unregisterCollider(colliderHandle) {
|
|
54
|
+
this._colliderEntityMap.delete(colliderHandle);
|
|
55
|
+
}
|
|
56
|
+
// Body factories
|
|
57
|
+
createDynamicBody() {
|
|
58
|
+
const desc = this._rapier.RigidBodyDesc.dynamic();
|
|
59
|
+
return this._world.createRigidBody(desc);
|
|
60
|
+
}
|
|
61
|
+
createFixedBody() {
|
|
62
|
+
const desc = this._rapier.RigidBodyDesc.fixed();
|
|
63
|
+
return this._world.createRigidBody(desc);
|
|
64
|
+
}
|
|
65
|
+
createKinematicPositionBody() {
|
|
66
|
+
const desc = this._rapier.RigidBodyDesc.kinematicPositionBased();
|
|
67
|
+
return this._world.createRigidBody(desc);
|
|
68
|
+
}
|
|
69
|
+
createKinematicVelocityBody() {
|
|
70
|
+
const desc = this._rapier.RigidBodyDesc.kinematicVelocityBased();
|
|
71
|
+
return this._world.createRigidBody(desc);
|
|
72
|
+
}
|
|
73
|
+
createBodyFromDesc(desc) {
|
|
74
|
+
return this._world.createRigidBody(desc);
|
|
75
|
+
}
|
|
76
|
+
// Collider factories (with optional collision groups and active events)
|
|
77
|
+
createBallCollider(radius, parent, groups, activeEvents) {
|
|
78
|
+
const desc = this._rapier.ColliderDesc.ball(radius);
|
|
79
|
+
if (groups !== undefined) desc.setCollisionGroups(groups);
|
|
80
|
+
if (activeEvents !== undefined) desc.setActiveEvents(activeEvents);
|
|
81
|
+
return this._world.createCollider(desc, parent);
|
|
82
|
+
}
|
|
83
|
+
createCuboidCollider(hx, hy, parent, groups, activeEvents) {
|
|
84
|
+
const desc = this._rapier.ColliderDesc.cuboid(hx, hy);
|
|
85
|
+
if (groups !== undefined) desc.setCollisionGroups(groups);
|
|
86
|
+
if (activeEvents !== undefined) desc.setActiveEvents(activeEvents);
|
|
87
|
+
return this._world.createCollider(desc, parent);
|
|
88
|
+
}
|
|
89
|
+
createCapsuleCollider(halfHeight, radius, parent, groups, activeEvents) {
|
|
90
|
+
const desc = this._rapier.ColliderDesc.capsule(halfHeight, radius);
|
|
91
|
+
if (groups !== undefined) desc.setCollisionGroups(groups);
|
|
92
|
+
if (activeEvents !== undefined) desc.setActiveEvents(activeEvents);
|
|
93
|
+
return this._world.createCollider(desc, parent);
|
|
94
|
+
}
|
|
95
|
+
createConvexHullCollider(points, parent, groups, activeEvents) {
|
|
96
|
+
const desc = this._rapier.ColliderDesc.convexHull(points);
|
|
97
|
+
if (!desc) return null;
|
|
98
|
+
if (groups !== undefined) desc.setCollisionGroups(groups);
|
|
99
|
+
if (activeEvents !== undefined) desc.setActiveEvents(activeEvents);
|
|
100
|
+
return this._world.createCollider(desc, parent);
|
|
101
|
+
}
|
|
102
|
+
createTrimeshCollider(vertices, indices, parent) {
|
|
103
|
+
const desc = this._rapier.ColliderDesc.trimesh(vertices, indices);
|
|
104
|
+
return this._world.createCollider(desc, parent);
|
|
105
|
+
}
|
|
106
|
+
createColliderFromDesc(desc, parent) {
|
|
107
|
+
return this._world.createCollider(desc, parent);
|
|
108
|
+
}
|
|
109
|
+
// Accessors
|
|
110
|
+
getBody(handle) {
|
|
111
|
+
return this._world.getRigidBody(handle);
|
|
112
|
+
}
|
|
113
|
+
getCollider(handle) {
|
|
114
|
+
return this._world.getCollider(handle);
|
|
115
|
+
}
|
|
116
|
+
// Removal
|
|
117
|
+
removeBody(handle) {
|
|
118
|
+
const body = this._world.getRigidBody(handle);
|
|
119
|
+
this._world.removeRigidBody(body);
|
|
120
|
+
}
|
|
121
|
+
removeCollider(handle, wakeUp = true) {
|
|
122
|
+
const collider = this._world.getCollider(handle);
|
|
123
|
+
this._world.removeCollider(collider, wakeUp);
|
|
124
|
+
}
|
|
125
|
+
// Rapier module access (for creating descs in game code)
|
|
126
|
+
get rapier() {
|
|
127
|
+
return this._rapier;
|
|
128
|
+
}
|
|
129
|
+
dispose() {
|
|
130
|
+
this._collisionEvents.dispose();
|
|
131
|
+
this._world.free();
|
|
132
|
+
}
|
|
133
|
+
constructor(_rapier, _config, frameLengthMs){
|
|
134
|
+
this._rapier = _rapier;
|
|
135
|
+
this._config = _config;
|
|
136
|
+
this._colliderEntityMap = new ColliderEntityMap();
|
|
137
|
+
this._world = new _rapier.World({
|
|
138
|
+
x: _config.gravityX,
|
|
139
|
+
y: _config.gravityY
|
|
140
|
+
});
|
|
141
|
+
this._substeps = _config.substeps;
|
|
142
|
+
this._substepDt = frameLengthMs / 1000 / this._substeps;
|
|
143
|
+
this._world.timestep = this._substepDt;
|
|
144
|
+
this._collisionEvents = new CollisionEvents2d(_rapier);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=physics-world-manager-2d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/physics-world-manager-2d.ts"],"sourcesContent":["import { createLogger } from '@lagless/misc';\nimport { ColliderEntityMap } from '@lagless/physics-shared';\nimport { CollisionEvents2d } from './collision-events-2d.js';\nimport { PhysicsConfig2d } from './physics-config-2d.js';\nimport {\n RapierCollider2d,\n RapierColliderDesc2d,\n RapierEventQueue,\n RapierModule2d,\n RapierRigidBody2d,\n RapierRigidBodyDesc2d,\n RapierWorld2d,\n} from './rapier-types-2d.js';\n\nconst log = createLogger('PhysicsWorldManager2d');\n\nexport class PhysicsWorldManager2d {\n private _world: RapierWorld2d;\n private readonly _substeps: number;\n private readonly _substepDt: number;\n private readonly _collisionEvents: CollisionEvents2d;\n private readonly _colliderEntityMap = new ColliderEntityMap();\n\n public get world(): RapierWorld2d {\n return this._world;\n }\n\n public get substeps(): number {\n return this._substeps;\n }\n\n public get colliderEntityMap(): ColliderEntityMap {\n return this._colliderEntityMap;\n }\n\n public get collisionEvents(): CollisionEvents2d {\n return this._collisionEvents;\n }\n\n constructor(\n private readonly _rapier: RapierModule2d,\n private readonly _config: PhysicsConfig2d,\n frameLengthMs: number,\n ) {\n this._world = new _rapier.World({\n x: _config.gravityX,\n y: _config.gravityY,\n });\n\n this._substeps = _config.substeps;\n this._substepDt = (frameLengthMs / 1000) / this._substeps;\n this._world.timestep = this._substepDt;\n this._collisionEvents = new CollisionEvents2d(_rapier);\n }\n\n /**\n * Step the physics world for one ECS frame.\n * Executes `substeps` Rapier steps, each with a fixed dt derived from frameLength / substeps.\n * When collision events are enabled, drains the event queue after all substeps.\n */\n public step(): void {\n const eq = this._collisionEvents.eventQueue as RapierEventQueue;\n for (let i = 0; i < this._substeps; i++) {\n this._world.step(eq);\n }\n this._collisionEvents.drain(this._colliderEntityMap, this._world);\n }\n\n public takeSnapshot(): Uint8Array {\n return this._world.takeSnapshot();\n }\n\n public restoreSnapshot(data: Uint8Array): void {\n this._world.free();\n const restored = this._rapier.World.restoreSnapshot(data);\n if (!restored) {\n log.warn('Failed to restore Rapier snapshot, recreating world');\n this._world = new this._rapier.World({\n x: this._config.gravityX,\n y: this._config.gravityY,\n });\n return;\n }\n this._world = restored;\n // CRITICAL: QueryPipeline is NOT included in the Rapier snapshot format.\n // After restoreSnapshot(), the world has a fresh empty QueryPipeline.\n // Any scene queries (ray casts, shape casts) will return wrong results until rebuilt.\n this._world.updateSceneQueries();\n }\n\n // Entity-collider mapping\n public registerCollider(colliderHandle: number, entity: number): void {\n this._colliderEntityMap.set(colliderHandle, entity);\n }\n\n public unregisterCollider(colliderHandle: number): void {\n this._colliderEntityMap.delete(colliderHandle);\n }\n\n // Body factories\n public createDynamicBody(): RapierRigidBody2d {\n const desc = this._rapier.RigidBodyDesc.dynamic();\n return this._world.createRigidBody(desc);\n }\n\n public createFixedBody(): RapierRigidBody2d {\n const desc = this._rapier.RigidBodyDesc.fixed();\n return this._world.createRigidBody(desc);\n }\n\n public createKinematicPositionBody(): RapierRigidBody2d {\n const desc = this._rapier.RigidBodyDesc.kinematicPositionBased();\n return this._world.createRigidBody(desc);\n }\n\n public createKinematicVelocityBody(): RapierRigidBody2d {\n const desc = this._rapier.RigidBodyDesc.kinematicVelocityBased();\n return this._world.createRigidBody(desc);\n }\n\n public createBodyFromDesc(desc: RapierRigidBodyDesc2d): RapierRigidBody2d {\n return this._world.createRigidBody(desc);\n }\n\n // Collider factories (with optional collision groups and active events)\n public createBallCollider(\n radius: number,\n parent?: RapierRigidBody2d,\n groups?: number,\n activeEvents?: number,\n ): RapierCollider2d {\n const desc = this._rapier.ColliderDesc.ball(radius);\n if (groups !== undefined) desc.setCollisionGroups(groups);\n if (activeEvents !== undefined) desc.setActiveEvents(activeEvents);\n return this._world.createCollider(desc, parent);\n }\n\n public createCuboidCollider(\n hx: number, hy: number,\n parent?: RapierRigidBody2d,\n groups?: number,\n activeEvents?: number,\n ): RapierCollider2d {\n const desc = this._rapier.ColliderDesc.cuboid(hx, hy);\n if (groups !== undefined) desc.setCollisionGroups(groups);\n if (activeEvents !== undefined) desc.setActiveEvents(activeEvents);\n return this._world.createCollider(desc, parent);\n }\n\n public createCapsuleCollider(\n halfHeight: number, radius: number,\n parent?: RapierRigidBody2d,\n groups?: number,\n activeEvents?: number,\n ): RapierCollider2d {\n const desc = this._rapier.ColliderDesc.capsule(halfHeight, radius);\n if (groups !== undefined) desc.setCollisionGroups(groups);\n if (activeEvents !== undefined) desc.setActiveEvents(activeEvents);\n return this._world.createCollider(desc, parent);\n }\n\n public createConvexHullCollider(\n points: Float32Array,\n parent?: RapierRigidBody2d,\n groups?: number,\n activeEvents?: number,\n ): RapierCollider2d | null {\n const desc = this._rapier.ColliderDesc.convexHull(points);\n if (!desc) return null;\n if (groups !== undefined) desc.setCollisionGroups(groups);\n if (activeEvents !== undefined) desc.setActiveEvents(activeEvents);\n return this._world.createCollider(desc, parent);\n }\n\n public createTrimeshCollider(\n vertices: Float32Array,\n indices: Uint32Array,\n parent?: RapierRigidBody2d,\n ): RapierCollider2d {\n const desc = this._rapier.ColliderDesc.trimesh(vertices, indices);\n return this._world.createCollider(desc, parent);\n }\n\n public createColliderFromDesc(desc: RapierColliderDesc2d, parent?: RapierRigidBody2d): RapierCollider2d {\n return this._world.createCollider(desc, parent);\n }\n\n // Accessors\n public getBody(handle: number): RapierRigidBody2d {\n return this._world.getRigidBody(handle);\n }\n\n public getCollider(handle: number): RapierCollider2d {\n return this._world.getCollider(handle);\n }\n\n // Removal\n public removeBody(handle: number): void {\n const body = this._world.getRigidBody(handle);\n this._world.removeRigidBody(body);\n }\n\n public removeCollider(handle: number, wakeUp = true): void {\n const collider = this._world.getCollider(handle);\n this._world.removeCollider(collider, wakeUp);\n }\n\n // Rapier module access (for creating descs in game code)\n public get rapier(): RapierModule2d {\n return this._rapier;\n }\n\n public dispose(): void {\n this._collisionEvents.dispose();\n this._world.free();\n }\n}\n"],"names":["createLogger","ColliderEntityMap","CollisionEvents2d","log","PhysicsWorldManager2d","world","_world","substeps","_substeps","colliderEntityMap","_colliderEntityMap","collisionEvents","_collisionEvents","step","eq","eventQueue","i","drain","takeSnapshot","restoreSnapshot","data","free","restored","_rapier","World","warn","x","_config","gravityX","y","gravityY","updateSceneQueries","registerCollider","colliderHandle","entity","set","unregisterCollider","delete","createDynamicBody","desc","RigidBodyDesc","dynamic","createRigidBody","createFixedBody","fixed","createKinematicPositionBody","kinematicPositionBased","createKinematicVelocityBody","kinematicVelocityBased","createBodyFromDesc","createBallCollider","radius","parent","groups","activeEvents","ColliderDesc","ball","undefined","setCollisionGroups","setActiveEvents","createCollider","createCuboidCollider","hx","hy","cuboid","createCapsuleCollider","halfHeight","capsule","createConvexHullCollider","points","convexHull","createTrimeshCollider","vertices","indices","trimesh","createColliderFromDesc","getBody","handle","getRigidBody","getCollider","removeBody","body","removeRigidBody","removeCollider","wakeUp","collider","rapier","dispose","constructor","frameLengthMs","_substepDt","timestep"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal type abstractions for Rapier 2D API.
|
|
3
|
+
* Works with both @dimforge/rapier2d and @dimforge/rapier2d-compat.
|
|
4
|
+
* The consumer project injects the actual RAPIER module at runtime.
|
|
5
|
+
*/
|
|
6
|
+
export interface RapierVector2 {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
}
|
|
10
|
+
export interface RapierRigidBody2d {
|
|
11
|
+
handle: number;
|
|
12
|
+
translation(): RapierVector2;
|
|
13
|
+
rotation(): number;
|
|
14
|
+
linvel(): RapierVector2;
|
|
15
|
+
angvel(): number;
|
|
16
|
+
setTranslation(translation: RapierVector2, wakeUp: boolean): void;
|
|
17
|
+
setRotation(angle: number, wakeUp: boolean): void;
|
|
18
|
+
setLinvel(linvel: RapierVector2, wakeUp: boolean): void;
|
|
19
|
+
setAngvel(angvel: number, wakeUp: boolean): void;
|
|
20
|
+
setLinearDamping(damping: number): void;
|
|
21
|
+
setAngularDamping(damping: number): void;
|
|
22
|
+
setAdditionalMass(mass: number): void;
|
|
23
|
+
isKinematic(): boolean;
|
|
24
|
+
isDynamic(): boolean;
|
|
25
|
+
isFixed(): boolean;
|
|
26
|
+
setNextKinematicTranslation(translation: RapierVector2): void;
|
|
27
|
+
setNextKinematicRotation(angle: number): void;
|
|
28
|
+
}
|
|
29
|
+
export interface RapierCollider2d {
|
|
30
|
+
handle: number;
|
|
31
|
+
parent(): RapierRigidBody2d | null;
|
|
32
|
+
isSensor(): boolean;
|
|
33
|
+
collisionGroups(): number;
|
|
34
|
+
setCollisionGroups(groups: number): void;
|
|
35
|
+
setActiveEvents(events: number): void;
|
|
36
|
+
setSensor(isSensor: boolean): void;
|
|
37
|
+
}
|
|
38
|
+
export interface RapierRigidBodyDesc2d {
|
|
39
|
+
setTranslation(x: number, y: number): RapierRigidBodyDesc2d;
|
|
40
|
+
setRotation(angle: number): RapierRigidBodyDesc2d;
|
|
41
|
+
setLinearDamping(damping: number): RapierRigidBodyDesc2d;
|
|
42
|
+
setAngularDamping(damping: number): RapierRigidBodyDesc2d;
|
|
43
|
+
setAdditionalMass(mass: number): RapierRigidBodyDesc2d;
|
|
44
|
+
}
|
|
45
|
+
export interface RapierColliderDesc2d {
|
|
46
|
+
setTranslation(x: number, y: number): RapierColliderDesc2d;
|
|
47
|
+
setRotation(angle: number): RapierColliderDesc2d;
|
|
48
|
+
setRestitution(restitution: number): RapierColliderDesc2d;
|
|
49
|
+
setFriction(friction: number): RapierColliderDesc2d;
|
|
50
|
+
setDensity(density: number): RapierColliderDesc2d;
|
|
51
|
+
setMass(mass: number): RapierColliderDesc2d;
|
|
52
|
+
setSensor(isSensor: boolean): RapierColliderDesc2d;
|
|
53
|
+
setCollisionGroups(groups: number): RapierColliderDesc2d;
|
|
54
|
+
setActiveEvents(events: number): RapierColliderDesc2d;
|
|
55
|
+
}
|
|
56
|
+
export interface RapierEventQueue {
|
|
57
|
+
free(): void;
|
|
58
|
+
drainCollisionEvents(f: (h1: number, h2: number, started: boolean) => void): void;
|
|
59
|
+
drainContactForceEvents(f: (event: RapierTempContactForceEvent2d) => void): void;
|
|
60
|
+
clear(): void;
|
|
61
|
+
}
|
|
62
|
+
export interface RapierTempContactForceEvent2d {
|
|
63
|
+
collider1(): number;
|
|
64
|
+
collider2(): number;
|
|
65
|
+
totalForceMagnitude(): number;
|
|
66
|
+
maxForceMagnitude(): number;
|
|
67
|
+
maxForceDirection(): RapierVector2;
|
|
68
|
+
}
|
|
69
|
+
export interface RapierWorld2d {
|
|
70
|
+
timestep: number;
|
|
71
|
+
step(eventQueue?: RapierEventQueue): void;
|
|
72
|
+
free(): void;
|
|
73
|
+
takeSnapshot(): Uint8Array;
|
|
74
|
+
getRigidBody(handle: number): RapierRigidBody2d;
|
|
75
|
+
getCollider(handle: number): RapierCollider2d;
|
|
76
|
+
createRigidBody(desc: RapierRigidBodyDesc2d): RapierRigidBody2d;
|
|
77
|
+
createCollider(desc: RapierColliderDesc2d, parent?: RapierRigidBody2d): RapierCollider2d;
|
|
78
|
+
removeRigidBody(body: RapierRigidBody2d): void;
|
|
79
|
+
removeCollider(collider: RapierCollider2d, wakeUp: boolean): void;
|
|
80
|
+
/** Rebuilds the query pipeline (BVH) from current collider positions. Must be called after restoreSnapshot(). */
|
|
81
|
+
updateSceneQueries(): void;
|
|
82
|
+
}
|
|
83
|
+
export interface RapierModule2d {
|
|
84
|
+
World: {
|
|
85
|
+
new (gravity: RapierVector2): RapierWorld2d;
|
|
86
|
+
restoreSnapshot(data: Uint8Array): RapierWorld2d | null;
|
|
87
|
+
};
|
|
88
|
+
RigidBodyDesc: {
|
|
89
|
+
dynamic(): RapierRigidBodyDesc2d;
|
|
90
|
+
fixed(): RapierRigidBodyDesc2d;
|
|
91
|
+
kinematicPositionBased(): RapierRigidBodyDesc2d;
|
|
92
|
+
kinematicVelocityBased(): RapierRigidBodyDesc2d;
|
|
93
|
+
};
|
|
94
|
+
ColliderDesc: {
|
|
95
|
+
ball(radius: number): RapierColliderDesc2d;
|
|
96
|
+
cuboid(hx: number, hy: number): RapierColliderDesc2d;
|
|
97
|
+
capsule(halfHeight: number, radius: number): RapierColliderDesc2d;
|
|
98
|
+
trimesh(vertices: Float32Array, indices: Uint32Array): RapierColliderDesc2d;
|
|
99
|
+
convexHull(points: Float32Array): RapierColliderDesc2d | null;
|
|
100
|
+
};
|
|
101
|
+
EventQueue: {
|
|
102
|
+
new (autoDrain: boolean): RapierEventQueue;
|
|
103
|
+
};
|
|
104
|
+
ActiveEvents: {
|
|
105
|
+
NONE: number;
|
|
106
|
+
COLLISION_EVENTS: number;
|
|
107
|
+
CONTACT_FORCE_EVENTS: number;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=rapier-types-2d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rapier-types-2d.d.ts","sourceRoot":"","sources":["../../src/lib/rapier-types-2d.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/rapier-types-2d.ts"],"sourcesContent":["/**\n * Minimal type abstractions for Rapier 2D API.\n * Works with both @dimforge/rapier2d and @dimforge/rapier2d-compat.\n * The consumer project injects the actual RAPIER module at runtime.\n */\n\nexport interface RapierVector2 {\n x: number;\n y: number;\n}\n\nexport interface RapierRigidBody2d {\n handle: number;\n translation(): RapierVector2;\n rotation(): number;\n linvel(): RapierVector2;\n angvel(): number;\n setTranslation(translation: RapierVector2, wakeUp: boolean): void;\n setRotation(angle: number, wakeUp: boolean): void;\n setLinvel(linvel: RapierVector2, wakeUp: boolean): void;\n setAngvel(angvel: number, wakeUp: boolean): void;\n setLinearDamping(damping: number): void;\n setAngularDamping(damping: number): void;\n setAdditionalMass(mass: number): void;\n isKinematic(): boolean;\n isDynamic(): boolean;\n isFixed(): boolean;\n setNextKinematicTranslation(translation: RapierVector2): void;\n setNextKinematicRotation(angle: number): void;\n}\n\nexport interface RapierCollider2d {\n handle: number;\n parent(): RapierRigidBody2d | null;\n isSensor(): boolean;\n collisionGroups(): number;\n setCollisionGroups(groups: number): void;\n setActiveEvents(events: number): void;\n setSensor(isSensor: boolean): void;\n}\n\nexport interface RapierRigidBodyDesc2d {\n setTranslation(x: number, y: number): RapierRigidBodyDesc2d;\n setRotation(angle: number): RapierRigidBodyDesc2d;\n setLinearDamping(damping: number): RapierRigidBodyDesc2d;\n setAngularDamping(damping: number): RapierRigidBodyDesc2d;\n setAdditionalMass(mass: number): RapierRigidBodyDesc2d;\n}\n\nexport interface RapierColliderDesc2d {\n setTranslation(x: number, y: number): RapierColliderDesc2d;\n setRotation(angle: number): RapierColliderDesc2d;\n setRestitution(restitution: number): RapierColliderDesc2d;\n setFriction(friction: number): RapierColliderDesc2d;\n setDensity(density: number): RapierColliderDesc2d;\n setMass(mass: number): RapierColliderDesc2d;\n setSensor(isSensor: boolean): RapierColliderDesc2d;\n setCollisionGroups(groups: number): RapierColliderDesc2d;\n setActiveEvents(events: number): RapierColliderDesc2d;\n}\n\nexport interface RapierEventQueue {\n free(): void;\n drainCollisionEvents(f: (h1: number, h2: number, started: boolean) => void): void;\n drainContactForceEvents(f: (event: RapierTempContactForceEvent2d) => void): void;\n clear(): void;\n}\n\nexport interface RapierTempContactForceEvent2d {\n collider1(): number;\n collider2(): number;\n totalForceMagnitude(): number;\n maxForceMagnitude(): number;\n maxForceDirection(): RapierVector2;\n}\n\nexport interface RapierWorld2d {\n timestep: number;\n step(eventQueue?: RapierEventQueue): void;\n free(): void;\n takeSnapshot(): Uint8Array;\n getRigidBody(handle: number): RapierRigidBody2d;\n getCollider(handle: number): RapierCollider2d;\n createRigidBody(desc: RapierRigidBodyDesc2d): RapierRigidBody2d;\n createCollider(desc: RapierColliderDesc2d, parent?: RapierRigidBody2d): RapierCollider2d;\n removeRigidBody(body: RapierRigidBody2d): void;\n removeCollider(collider: RapierCollider2d, wakeUp: boolean): void;\n /** Rebuilds the query pipeline (BVH) from current collider positions. Must be called after restoreSnapshot(). */\n updateSceneQueries(): void;\n}\n\nexport interface RapierModule2d {\n World: {\n new (gravity: RapierVector2): RapierWorld2d;\n restoreSnapshot(data: Uint8Array): RapierWorld2d | null;\n };\n RigidBodyDesc: {\n dynamic(): RapierRigidBodyDesc2d;\n fixed(): RapierRigidBodyDesc2d;\n kinematicPositionBased(): RapierRigidBodyDesc2d;\n kinematicVelocityBased(): RapierRigidBodyDesc2d;\n };\n ColliderDesc: {\n ball(radius: number): RapierColliderDesc2d;\n cuboid(hx: number, hy: number): RapierColliderDesc2d;\n capsule(halfHeight: number, radius: number): RapierColliderDesc2d;\n trimesh(vertices: Float32Array, indices: Uint32Array): RapierColliderDesc2d;\n convexHull(points: Float32Array): RapierColliderDesc2d | null;\n };\n EventQueue: {\n new (autoDrain: boolean): RapierEventQueue;\n };\n ActiveEvents: {\n NONE: number;\n COLLISION_EVENTS: number;\n CONTACT_FORCE_EVENTS: number;\n };\n}\n"],"names":[],"rangeMappings":";;;;","mappings":"AAAA;;;;CAIC,GAuFD,WA0BC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"5.9.3"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lagless/physics2d",
|
|
3
|
+
"version": "0.0.39",
|
|
4
|
+
"license": "CC-BY-NC-4.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/GbGr/lagless",
|
|
8
|
+
"directory": "libs/physics2d"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"module": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
"./package.json": "./package.json",
|
|
16
|
+
".": {
|
|
17
|
+
"@lagless/source": "./src/index.ts",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"nx": {
|
|
24
|
+
"sourceRoot": "libs/physics2d/src",
|
|
25
|
+
"targets": {
|
|
26
|
+
"build": {
|
|
27
|
+
"executor": "@nx/js:swc",
|
|
28
|
+
"outputs": [
|
|
29
|
+
"{options.outputPath}"
|
|
30
|
+
],
|
|
31
|
+
"options": {
|
|
32
|
+
"outputPath": "libs/physics2d/dist",
|
|
33
|
+
"main": "libs/physics2d/src/index.ts",
|
|
34
|
+
"tsConfig": "libs/physics2d/tsconfig.lib.json",
|
|
35
|
+
"stripLeadingPaths": true
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@swc/helpers": "~0.5.11",
|
|
42
|
+
"@lagless/core": "0.0.39",
|
|
43
|
+
"@lagless/misc": "0.0.39",
|
|
44
|
+
"@lagless/physics-shared": "0.0.39"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@dimforge/rapier2d-compat": ">=0.14.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@dimforge/rapier2d-compat": "^0.14.0",
|
|
51
|
+
"unplugin-swc": "^1.5.7"
|
|
52
|
+
},
|
|
53
|
+
"files": [
|
|
54
|
+
"dist",
|
|
55
|
+
"README.md"
|
|
56
|
+
],
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
}
|
|
60
|
+
}
|