@ignifx/physics-2d 0.0.0 → 0.2.0
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 +201 -0
- package/dist/index.d.ts +1686 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3881 -0
- package/dist/index.js.map +1 -0
- package/package.json +31 -26
- package/skills/physics-2d/SKILL.md +249 -13
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,1686 @@
|
|
|
1
|
-
|
|
1
|
+
import { AssetHandle, AssetLoader, Component, ComponentHooks, DiagnosticsGroup, Disconnect, Entity, ErrorContext, Extension, ExtensionContext, IgnifxError, JsonValue, LayerMask, MutableVec2, Schema, SchemaDescription, Signal, Vec2, Vec2Like } from "@ignifx/core";
|
|
2
|
+
import { Collider, EventQueue, RigidBody, World } from "@dimforge/rapier2d-compat";
|
|
3
|
+
import { TilemapCollisionData } from "@ignifx/2d";
|
|
4
|
+
//#region src/settings.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* The `physics2d` project settings section (`docs/architecture/11-2d-toolkit.md` §8,
|
|
7
|
+
* `09-physics.md` §6). It mirrors the 3D `physics` section with a 2D gravity vector and Rapier's
|
|
8
|
+
* solver knob in place of Havok's world velocity clamps, which Rapier has no equivalent of.
|
|
9
|
+
*
|
|
10
|
+
* `fixedDeltaTime` is **not** here: the fixed step is shared with the core `time` section and the
|
|
11
|
+
* extension reads it from `app.time.fixedDeltaTime` on every step.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The section name as it appears in `ignifx.config.ts`.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare const PHYSICS_2D_SETTINGS_SECTION = "physics2d";
|
|
19
|
+
/**
|
|
20
|
+
* A surface, either as the `physics2d.defaultMaterial` setting or inline on a collider.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
interface Physics2DMaterialValues {
|
|
25
|
+
/** The friction coefficient. */
|
|
26
|
+
readonly friction: number;
|
|
27
|
+
/** How much of the approach speed is returned, `0` to `1`. */
|
|
28
|
+
readonly restitution: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The resolved `physics2d` settings section.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* // ignifx.config.ts
|
|
36
|
+
* export default {
|
|
37
|
+
* layers: { layers: ["Default", "Player", "Enemy"] },
|
|
38
|
+
* physics2d: {
|
|
39
|
+
* gravity: { x: 0, y: -9.81 },
|
|
40
|
+
* collisionMatrix: { Player: ["Default", "Enemy"], Enemy: ["Default"] },
|
|
41
|
+
* },
|
|
42
|
+
* };
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
interface Physics2DSettings {
|
|
48
|
+
/** World gravity in metres per second squared; +Y is up (`11-2d-toolkit.md` §3). */
|
|
49
|
+
readonly gravity: Vec2Like;
|
|
50
|
+
/**
|
|
51
|
+
* Which layers each layer collides with. A layer the map does not mention collides with
|
|
52
|
+
* everything, which is what makes the default project need no matrix at all.
|
|
53
|
+
*/
|
|
54
|
+
readonly collisionMatrix: Readonly<Record<string, readonly string[]>>;
|
|
55
|
+
/** The surface a collider with no material of its own uses. */
|
|
56
|
+
readonly defaultMaterial: Physics2DMaterialValues;
|
|
57
|
+
/** How many iterations Rapier's constraint solver runs; `0` leaves Rapier's own default (4). */
|
|
58
|
+
readonly velocityIterations: number;
|
|
59
|
+
/** Whether dynamic bodies and character controllers interpolate between fixed steps. */
|
|
60
|
+
readonly interpolation: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Builds the schema the `physics2d` section is validated against.
|
|
64
|
+
*
|
|
65
|
+
* @remarks
|
|
66
|
+
* It is a function, not a module-level constant: every field kind is a function call, and module
|
|
67
|
+
* scope holds declarations and immutable constants only (`CONSTITUTION.md` §3.5).
|
|
68
|
+
*
|
|
69
|
+
* @returns The schema.
|
|
70
|
+
*
|
|
71
|
+
* @public
|
|
72
|
+
*/
|
|
73
|
+
export declare function physics2DSettingsSchema(): Schema;
|
|
74
|
+
/**
|
|
75
|
+
* The values used when a project omits the `physics2d` section.
|
|
76
|
+
*
|
|
77
|
+
* @returns A fresh defaults object.
|
|
78
|
+
*
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export declare function defaultPhysics2DSettings(): Physics2DSettings;
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/material.d.ts
|
|
84
|
+
/**
|
|
85
|
+
* The `ignifx.physicsmaterial` asset, read by the 2D extension.
|
|
86
|
+
*
|
|
87
|
+
* ## Why the format is the 3D one
|
|
88
|
+
*
|
|
89
|
+
* `11-2d-toolkit.md` §8 lists a `PhysicsMaterial2D`, and `09-physics.md` §2.4 already defines
|
|
90
|
+
* `{ "format": "ignifx.physicsmaterial", "friction": …, "staticFriction": …, "restitution": … }`.
|
|
91
|
+
* Inventing a second document for the same two numbers would give artists two files to keep in
|
|
92
|
+
* step, so this package reads **the same format and the same `.physicsmaterial.json` extension**,
|
|
93
|
+
* ignoring `staticFriction` (Rapier 2D has one friction coefficient, `geometry/collider.d.ts`).
|
|
94
|
+
* `@ignifx/physics` and `@ignifx/physics-2d` never run in one world — `IGX-1101` — so the two
|
|
95
|
+
* loaders never collide.
|
|
96
|
+
*
|
|
97
|
+
* The 2D-only knobs, how two surfaces' friction and restitution are **combined**, are fields on the
|
|
98
|
+
* collider rather than on the asset, so the document stays byte-identical to the 3D one.
|
|
99
|
+
*/
|
|
100
|
+
/**
|
|
101
|
+
* The asset type name `.physicsmaterial.json` addresses resolve to.
|
|
102
|
+
*
|
|
103
|
+
* @public
|
|
104
|
+
*/
|
|
105
|
+
export declare const PHYSICS_MATERIAL_2D_ASSET_TYPE = "physicsmaterial";
|
|
106
|
+
/**
|
|
107
|
+
* The address suffix that selects the loader.
|
|
108
|
+
*
|
|
109
|
+
* @public
|
|
110
|
+
*/
|
|
111
|
+
export declare const PHYSICS_MATERIAL_2D_FILE_EXTENSION = ".physicsmaterial.json";
|
|
112
|
+
/**
|
|
113
|
+
* The `format` string every physics-material document declares.
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
116
|
+
*/
|
|
117
|
+
export declare const PHYSICS_MATERIAL_2D_FILE_FORMAT = "ignifx.physicsmaterial";
|
|
118
|
+
/**
|
|
119
|
+
* The file format version; `1` before ignifx 1.0.
|
|
120
|
+
*
|
|
121
|
+
* @public
|
|
122
|
+
*/
|
|
123
|
+
export declare const PHYSICS_MATERIAL_2D_FORMAT_VERSION = 1;
|
|
124
|
+
/**
|
|
125
|
+
* A loaded 2D surface.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* const ice = await app.assets.load<PhysicsMaterial2D>("materials/ice.physicsmaterial.json");
|
|
130
|
+
* floor.addComponent(BoxCollider2D, { size: { x: 10, y: 1 }, material: ice });
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @public
|
|
134
|
+
*/
|
|
135
|
+
export declare class PhysicsMaterial2D implements Physics2DMaterialValues {
|
|
136
|
+
/** The asset type token, so `asset(PhysicsMaterial2D)` fields resolve. */
|
|
137
|
+
static assetType: string;
|
|
138
|
+
/** A human-readable name, used in diagnostics. */
|
|
139
|
+
readonly name: string;
|
|
140
|
+
/** The friction coefficient. */
|
|
141
|
+
readonly friction: number;
|
|
142
|
+
/** How much of the approach speed is returned, `0` to `1`. */
|
|
143
|
+
readonly restitution: number;
|
|
144
|
+
/**
|
|
145
|
+
* Wraps parsed values.
|
|
146
|
+
*
|
|
147
|
+
* @param name - A human-readable name.
|
|
148
|
+
* @param values - Friction and restitution.
|
|
149
|
+
*/
|
|
150
|
+
constructor(name: string, values: Physics2DMaterialValues);
|
|
151
|
+
/**
|
|
152
|
+
* Builds a material in code, filling in the fields the caller omitted.
|
|
153
|
+
*
|
|
154
|
+
* @param name - A human-readable name.
|
|
155
|
+
* @param values - Any subset of the two coefficients.
|
|
156
|
+
* @returns The material.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* const bouncy = PhysicsMaterial2D.fromValues("bouncy", { restitution: 0.9 });
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
static fromValues(name: string, values: Partial<Physics2DMaterialValues>): PhysicsMaterial2D;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Builds the loader for `.physicsmaterial.json` files.
|
|
167
|
+
*
|
|
168
|
+
* @returns The loader, ready for `ctx.registerAssetLoader`.
|
|
169
|
+
*
|
|
170
|
+
* @public
|
|
171
|
+
*/
|
|
172
|
+
export declare function createPhysicsMaterial2DLoader(): AssetLoader<PhysicsMaterial2D>;
|
|
173
|
+
/**
|
|
174
|
+
* Parses one `ignifx.physicsmaterial` document into a 2D surface.
|
|
175
|
+
*
|
|
176
|
+
* @param address - The address it came from, for the diagnostic.
|
|
177
|
+
* @param document - The parsed JSON.
|
|
178
|
+
* @returns The material.
|
|
179
|
+
* @throws IgnifxError with code `IGX-1154` when the document is not one this build can read.
|
|
180
|
+
*
|
|
181
|
+
* @public
|
|
182
|
+
*/
|
|
183
|
+
export declare function parsePhysicsMaterial2D(address: string, document: JsonValue): PhysicsMaterial2D;
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/lite/rapier/world.d.ts
|
|
186
|
+
/**
|
|
187
|
+
* The Rapier 2D adapter (`docs/architecture/11-2d-toolkit.md` §8, ADR-0006). Everything the runtime
|
|
188
|
+
* needs from `@dimforge/rapier2d-compat` is a function here, so the rest of `src/` never imports the
|
|
189
|
+
* backend (`ignifx/no-lite-outside-adapter`, coding standards §4).
|
|
190
|
+
*
|
|
191
|
+
* ## Facts measured against `@dimforge/rapier2d-compat@0.20.0` (spike S6.2)
|
|
192
|
+
*
|
|
193
|
+
* - **The broadphase is only built by `World.step`.** Before the first step, `castRay` returns
|
|
194
|
+
* `null` and `KinematicCharacterController.computeColliderMovement` reports the full requested
|
|
195
|
+
* motion with no obstacles; a collider created after the last step is invisible until the next
|
|
196
|
+
* one. {@link primeWorld} runs a zero-length step, which builds the broadphase without
|
|
197
|
+
* integrating — but it is *not* free of side effects on a running simulation (a settled pile
|
|
198
|
+
* hashes differently), so the runtime primes only when the collider set changed.
|
|
199
|
+
* - **`InteractionGroups` is one 32-bit number**: membership in the high 16 bits, filter in the low
|
|
200
|
+
* 16 (`geometry/interaction_groups.d.ts`). Sixteen layers, not thirty-two.
|
|
201
|
+
* - **`ActiveCollisionTypes.DEFAULT` excludes non-dynamic pairs**, so a kinematic character never
|
|
202
|
+
* reports entering a static sensor. Colliders that want events are given
|
|
203
|
+
* `ActiveCollisionTypes.ALL`.
|
|
204
|
+
*/
|
|
205
|
+
/**
|
|
206
|
+
* Rapier's physics world.
|
|
207
|
+
*
|
|
208
|
+
* @internal
|
|
209
|
+
*/
|
|
210
|
+
type RapierWorld = World;
|
|
211
|
+
/**
|
|
212
|
+
* One Rapier rigid body.
|
|
213
|
+
*
|
|
214
|
+
* @internal
|
|
215
|
+
*/
|
|
216
|
+
type RapierBody = RigidBody;
|
|
217
|
+
/**
|
|
218
|
+
* One Rapier collider.
|
|
219
|
+
*
|
|
220
|
+
* @internal
|
|
221
|
+
*/
|
|
222
|
+
type RapierCollider = Collider;
|
|
223
|
+
/**
|
|
224
|
+
* How a body moves, in the three flavours ignifx exposes.
|
|
225
|
+
*
|
|
226
|
+
* @internal
|
|
227
|
+
*/
|
|
228
|
+
declare const BodyMotion2D: {
|
|
229
|
+
/** Simulated by the solver. */
|
|
230
|
+
readonly dynamic: "dynamic";
|
|
231
|
+
/** Moved by the game, pushes dynamic bodies, ignores forces. */
|
|
232
|
+
readonly kinematic: "kinematic";
|
|
233
|
+
/** Never moves. */
|
|
234
|
+
readonly static: "static";
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* The union of {@link BodyMotion2D}.
|
|
238
|
+
*
|
|
239
|
+
* @internal
|
|
240
|
+
*/
|
|
241
|
+
type BodyMotion2D = (typeof BodyMotion2D)[keyof typeof BodyMotion2D];
|
|
242
|
+
/**
|
|
243
|
+
* A collision shape, described in metres in the body's local frame.
|
|
244
|
+
*
|
|
245
|
+
* @internal
|
|
246
|
+
*/
|
|
247
|
+
type RapierShape2D = {
|
|
248
|
+
readonly kind: "box";
|
|
249
|
+
readonly halfWidth: number;
|
|
250
|
+
readonly halfHeight: number;
|
|
251
|
+
} | {
|
|
252
|
+
readonly kind: "circle";
|
|
253
|
+
readonly radius: number;
|
|
254
|
+
} | {
|
|
255
|
+
readonly kind: "capsule";
|
|
256
|
+
readonly halfHeight: number;
|
|
257
|
+
readonly radius: number;
|
|
258
|
+
} | {
|
|
259
|
+
readonly kind: "polygon";
|
|
260
|
+
readonly points: Float32Array;
|
|
261
|
+
} | {
|
|
262
|
+
readonly kind: "polyline";
|
|
263
|
+
readonly points: Float32Array;
|
|
264
|
+
};
|
|
265
|
+
//#endregion
|
|
266
|
+
//#region src/components/collider.d.ts
|
|
267
|
+
/**
|
|
268
|
+
* The 2D collider contract (`docs/architecture/11-2d-toolkit.md` §8). Every collider shares an
|
|
269
|
+
* offset, the trigger flag, a surface, a layer override, and the one-way platform flag, and answers
|
|
270
|
+
* one question the body builder asks: which Rapier shapes it stands for.
|
|
271
|
+
*
|
|
272
|
+
* ## Corrections to §8
|
|
273
|
+
*
|
|
274
|
+
* - **The material is two fields, not a union.** A schema field has exactly one kind (ADR-0004), so
|
|
275
|
+
* {@link Collider2D.material} (an asset reference) and {@link Collider2D.inlineMaterial} (a
|
|
276
|
+
* record) are separate; the asset wins, the inline record is the fallback, and
|
|
277
|
+
* `physics2d.defaultMaterial` is the last resort. This is the same split `@ignifx/physics` makes.
|
|
278
|
+
* - **Combine rules are collider fields.** Rapier combines two surfaces' friction and restitution
|
|
279
|
+
* with a per-collider rule (`dynamics/coefficient_combine_rule.d.ts`); the 3D
|
|
280
|
+
* `ignifx.physicsmaterial` document has no such field, so the knob lives here rather than
|
|
281
|
+
* forking the asset format.
|
|
282
|
+
* - **A collider may stand for several Rapier colliders.** `TilemapCollider2D` produces one polygon
|
|
283
|
+
* per merged tile run, so {@link Collider2D.collectShapes} fills a list rather than returning one
|
|
284
|
+
* shape.
|
|
285
|
+
*
|
|
286
|
+
* ## Sizes and scale
|
|
287
|
+
*
|
|
288
|
+
* Sizes are authored in local metres and multiplied by the entity's lossy scale when the shapes are
|
|
289
|
+
* built. Rapier cannot rescale a built shape, so a later scale change needs
|
|
290
|
+
* {@link Collider2D.rebuild}.
|
|
291
|
+
*/
|
|
292
|
+
/**
|
|
293
|
+
* How two surfaces' coefficients are combined when they touch, mirroring Rapier's
|
|
294
|
+
* `CoefficientCombineRule`.
|
|
295
|
+
*
|
|
296
|
+
* @public
|
|
297
|
+
*/
|
|
298
|
+
export declare const COMBINE_RULES: readonly ["average", "min", "multiply", "max"];
|
|
299
|
+
/**
|
|
300
|
+
* The union of {@link COMBINE_RULES}.
|
|
301
|
+
*
|
|
302
|
+
* @public
|
|
303
|
+
*/
|
|
304
|
+
type CombineRule = (typeof COMBINE_RULES)[number];
|
|
305
|
+
/**
|
|
306
|
+
* One Rapier shape a collider stands for, positioned in the body's local frame.
|
|
307
|
+
*
|
|
308
|
+
* @internal
|
|
309
|
+
*/
|
|
310
|
+
interface CollectedShape2D {
|
|
311
|
+
/** The geometry. */
|
|
312
|
+
readonly shape: RapierShape2D;
|
|
313
|
+
/** Where it sits relative to the entity origin, in metres. */
|
|
314
|
+
readonly offset: Vec2Like;
|
|
315
|
+
/** How it is turned about that point, in radians counter-clockwise. */
|
|
316
|
+
readonly rotation: number;
|
|
317
|
+
/** Whether it is solid only when a character controller comes down onto it. */
|
|
318
|
+
readonly oneWay: boolean;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* The fields every 2D collider declares.
|
|
322
|
+
*
|
|
323
|
+
* @returns The shared field declarations, ready to spread into a collider's own schema.
|
|
324
|
+
*
|
|
325
|
+
* @public
|
|
326
|
+
*/
|
|
327
|
+
export declare function collider2DFields(): Schema;
|
|
328
|
+
/**
|
|
329
|
+
* The base class of every 2D collider.
|
|
330
|
+
*
|
|
331
|
+
* @public
|
|
332
|
+
*/
|
|
333
|
+
export declare abstract class Collider2D extends Component implements ComponentHooks {
|
|
334
|
+
/** Several colliders on one entity make one compound body. */
|
|
335
|
+
static allowMultiple: boolean;
|
|
336
|
+
/** The shape's offset from the entity origin, in local metres. */
|
|
337
|
+
offset: Vec2Like;
|
|
338
|
+
/** When `true` the shape reports overlaps and resolves no contacts. */
|
|
339
|
+
isTrigger: boolean;
|
|
340
|
+
/** A `.physicsmaterial.json` reference; wins over {@link Collider2D.inlineMaterial}. */
|
|
341
|
+
material: AssetHandle<PhysicsMaterial2D> | null;
|
|
342
|
+
/** An inline surface, used when {@link Collider2D.material} is `null`. */
|
|
343
|
+
inlineMaterial: Physics2DMaterialValues | null;
|
|
344
|
+
/** How this surface's friction combines with the one it touches. */
|
|
345
|
+
frictionCombine: CombineRule;
|
|
346
|
+
/** How this surface's restitution combines with the one it touches. */
|
|
347
|
+
restitutionCombine: CombineRule;
|
|
348
|
+
/**
|
|
349
|
+
* Whether this is a one-way platform: a `CharacterController2D` with
|
|
350
|
+
* `onOneWayPlatforms` passes up through it and lands on it coming down. Rigid bodies are
|
|
351
|
+
* unaffected — one-way support is a character-controller feature in the MVP.
|
|
352
|
+
*/
|
|
353
|
+
oneWay: boolean;
|
|
354
|
+
/** The name of the layer this collider filters as, or `""` to use `entity.layer`. */
|
|
355
|
+
layerOverride: string;
|
|
356
|
+
/** Applies the shared defaults. A concrete collider calls `super()` and then applies its own. */
|
|
357
|
+
constructor();
|
|
358
|
+
/** Marks the entity's body for a rebuild at the start of the next fixed step. */
|
|
359
|
+
onAttach(): void;
|
|
360
|
+
/** Marks the entity's body for a rebuild, which removes this collider from it. */
|
|
361
|
+
onDetach(): void;
|
|
362
|
+
/**
|
|
363
|
+
* Rebuilds the entity's body and shapes at the start of the next fixed step. Call it after
|
|
364
|
+
* changing a size, an offset, `isTrigger`, or the entity's scale.
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```ts
|
|
368
|
+
* box.size = { x: 2, y: 2 };
|
|
369
|
+
* box.rebuild();
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
rebuild(): void;
|
|
373
|
+
/**
|
|
374
|
+
* Resolves the surface this collider presents to Rapier.
|
|
375
|
+
*
|
|
376
|
+
* @param fallback - The world's `physics2d.defaultMaterial`.
|
|
377
|
+
* @returns The asset's values, the inline values, or the fallback.
|
|
378
|
+
*/
|
|
379
|
+
resolveMaterial(fallback: Physics2DMaterialValues): Physics2DMaterialValues;
|
|
380
|
+
/**
|
|
381
|
+
* Appends the Rapier shapes this collider stands for.
|
|
382
|
+
*
|
|
383
|
+
* @param scale - The entity's lossy scale in the 2D plane.
|
|
384
|
+
* @param out - The list to append to.
|
|
385
|
+
*
|
|
386
|
+
* @internal
|
|
387
|
+
*/
|
|
388
|
+
abstract collectShapes(scale: Vec2Like, out: CollectedShape2D[]): void;
|
|
389
|
+
}
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/events.d.ts
|
|
392
|
+
/**
|
|
393
|
+
* The payloads the five physics callbacks receive in 2D (`docs/architecture/11-2d-toolkit.md` §8,
|
|
394
|
+
* `09-physics.md` §4).
|
|
395
|
+
*
|
|
396
|
+
* ## The callbacks are the 3D names
|
|
397
|
+
*
|
|
398
|
+
* `11-2d-toolkit.md` §8 writes them as `onCollisionEnter2D`/`onTriggerEnter2D`. The kernel's
|
|
399
|
+
* `PhysicsCallbackName` union has five members and no `2D` variants
|
|
400
|
+
* (`packages/core/src/lifecycle/callbacks.ts`), and a world uses either `physics()` or
|
|
401
|
+
* `physics2d()` — never both, which is what `IGX-1101` enforces. So a 2D game implements
|
|
402
|
+
* `onCollisionEnter`, `onCollisionStay`, `onCollisionExit`, `onTriggerEnter`, and `onTriggerExit`,
|
|
403
|
+
* and receives the 2D payloads below. §8 is corrected accordingly.
|
|
404
|
+
*
|
|
405
|
+
* ## Identities are native
|
|
406
|
+
*
|
|
407
|
+
* Rapier reports **both** colliders of every event (`pipeline/event_queue.d.ts`,
|
|
408
|
+
* `drainCollisionEvents`), so `other` is never `null` for a live body and the ADR-0013 waiver that
|
|
409
|
+
* 3D physics needs has no counterpart here.
|
|
410
|
+
*
|
|
411
|
+
* Every payload is **pooled**: the same instances are reused for every event of a step, so a script
|
|
412
|
+
* that needs a value after its callback returns must copy it out (coding standards §7).
|
|
413
|
+
*/
|
|
414
|
+
/**
|
|
415
|
+
* One contact point of a 2D collision. Pooled with its owning {@link Collision2D}.
|
|
416
|
+
*
|
|
417
|
+
* @public
|
|
418
|
+
*/
|
|
419
|
+
interface ContactPoint2D {
|
|
420
|
+
/** The world-space contact point, in metres. */
|
|
421
|
+
readonly point: Vec2Like;
|
|
422
|
+
/** The world-space contact normal, pointing away from the other collider. */
|
|
423
|
+
readonly normal: Vec2Like;
|
|
424
|
+
/** The magnitude of the impulse Rapier's solver applied; `0` for a contact that just ended. */
|
|
425
|
+
readonly impulse: number;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* What a script's `onTriggerEnter`/`onTriggerExit` is handed in a 2D world.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```ts
|
|
432
|
+
* class Coin extends Script implements ScriptCallbacks {
|
|
433
|
+
* static typeId = "mygame/Coin";
|
|
434
|
+
* onTriggerEnter(trigger: TriggerEvent2D): void {
|
|
435
|
+
* if (trigger.other?.tags.has("player") === true) {
|
|
436
|
+
* this.entity.destroy();
|
|
437
|
+
* }
|
|
438
|
+
* }
|
|
439
|
+
* }
|
|
440
|
+
* ```
|
|
441
|
+
*
|
|
442
|
+
* @public
|
|
443
|
+
*/
|
|
444
|
+
interface TriggerEvent2D {
|
|
445
|
+
/** The entity that entered or left, or `null` when its body is already gone. */
|
|
446
|
+
readonly other: Entity | null;
|
|
447
|
+
/** The exact collider on the other entity — Rapier reports shape identity, unlike Havok. */
|
|
448
|
+
readonly otherCollider: Collider2D | null;
|
|
449
|
+
/** The entity whose script is being called. */
|
|
450
|
+
readonly self: Entity;
|
|
451
|
+
/** The collider on this entity that took part. */
|
|
452
|
+
readonly selfCollider: Collider2D | null;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* What a script's `onCollisionEnter`/`onCollisionStay`/`onCollisionExit` is handed in a 2D world.
|
|
456
|
+
*
|
|
457
|
+
* @public
|
|
458
|
+
*/
|
|
459
|
+
interface Collision2D {
|
|
460
|
+
/** The entity that was hit, or `null` when its body is already gone. */
|
|
461
|
+
readonly other: Entity | null;
|
|
462
|
+
/** The exact collider on the other entity. */
|
|
463
|
+
readonly otherCollider: Collider2D | null;
|
|
464
|
+
/** The entity whose script is being called. */
|
|
465
|
+
readonly self: Entity;
|
|
466
|
+
/** The collider on this entity that took part. */
|
|
467
|
+
readonly selfCollider: Collider2D | null;
|
|
468
|
+
/** The contacts of this event. Pooled; valid only during the callback. */
|
|
469
|
+
readonly contacts: readonly ContactPoint2D[];
|
|
470
|
+
/** The relative velocity of the two bodies at the contact, in metres per second. */
|
|
471
|
+
readonly relativeVelocity: Vec2Like;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* What `CharacterController2D.onCollided` reports: one obstacle the character hit this step.
|
|
475
|
+
*
|
|
476
|
+
* @public
|
|
477
|
+
*/
|
|
478
|
+
interface CharacterCollision2D {
|
|
479
|
+
/** The entity that was hit, or `null` when it is not an ignifx body. */
|
|
480
|
+
readonly other: Entity | null;
|
|
481
|
+
/** The collider that was hit, or `null`. */
|
|
482
|
+
readonly otherCollider: Collider2D | null;
|
|
483
|
+
/** The world-space contact point. */
|
|
484
|
+
readonly point: Vec2Like;
|
|
485
|
+
/** The world-space outward normal on the obstacle. */
|
|
486
|
+
readonly normal: Vec2Like;
|
|
487
|
+
}
|
|
488
|
+
//#endregion
|
|
489
|
+
//#region src/components/rigidbody.d.ts
|
|
490
|
+
/**
|
|
491
|
+
* The `Rigidbody2D` component (`docs/architecture/11-2d-toolkit.md` §8): what makes an entity's 2D
|
|
492
|
+
* colliders a simulated, kinematic, or explicitly static Rapier body.
|
|
493
|
+
*
|
|
494
|
+
* ## Decisions §8 leaves open
|
|
495
|
+
*
|
|
496
|
+
* - **`mass` is exact, and `0` means "weigh the colliders".** Rapier derives a body's mass and
|
|
497
|
+
* angular inertia from each collider's *density* and area (`geometry/collider.d.ts`,
|
|
498
|
+
* `setDensity`), and `setAdditionalMass` adds mass without inertia. So a non-zero `mass` is
|
|
499
|
+
* applied by scaling every collider's density until the body weighs exactly that, which keeps the
|
|
500
|
+
* inertia distribution the shapes imply; `mass: 0` leaves Rapier's own density of 1 kg/m² alone.
|
|
501
|
+
* - **`freezeRotation` is one boolean, not three.** A 2D body has one rotational degree of freedom
|
|
502
|
+
* (`dynamics/rigid_body.d.ts`, `lockRotations`).
|
|
503
|
+
* - **Damping is per body here, unlike 3D.** Havok has no per-body damping; Rapier does
|
|
504
|
+
* (`setLinearDamping`, `setAngularDamping`), so `linearDamping` and `angularDamping` are real
|
|
505
|
+
* fields rather than upstream requests.
|
|
506
|
+
* - **`collisionEvents` is a three-valued enum**, exactly as in `@ignifx/physics`: a schema field
|
|
507
|
+
* has one kind (ADR-0004), and `"auto"` recomputes from `ctx.entityImplements` whenever a
|
|
508
|
+
* component joins or leaves the entity.
|
|
509
|
+
*/
|
|
510
|
+
/**
|
|
511
|
+
* How a 2D body moves.
|
|
512
|
+
*
|
|
513
|
+
* @public
|
|
514
|
+
*/
|
|
515
|
+
export declare const BODY_TYPES_2D: readonly ["dynamic", "kinematic", "static"];
|
|
516
|
+
/**
|
|
517
|
+
* The union of {@link BODY_TYPES_2D}.
|
|
518
|
+
*
|
|
519
|
+
* @public
|
|
520
|
+
*/
|
|
521
|
+
type BodyType2D = (typeof BODY_TYPES_2D)[number];
|
|
522
|
+
/**
|
|
523
|
+
* Whether a body's display pose is interpolated between fixed steps.
|
|
524
|
+
*
|
|
525
|
+
* @public
|
|
526
|
+
*/
|
|
527
|
+
export declare const INTERPOLATION_MODES_2D: readonly ["none", "interpolate"];
|
|
528
|
+
/**
|
|
529
|
+
* The union of {@link INTERPOLATION_MODES_2D}.
|
|
530
|
+
*
|
|
531
|
+
* @public
|
|
532
|
+
*/
|
|
533
|
+
type InterpolationMode2D = (typeof INTERPOLATION_MODES_2D)[number];
|
|
534
|
+
/**
|
|
535
|
+
* Whether collision callbacks are delivered for this body.
|
|
536
|
+
*
|
|
537
|
+
* @public
|
|
538
|
+
*/
|
|
539
|
+
export declare const COLLISION_EVENT_MODES_2D: readonly ["auto", "on", "off"];
|
|
540
|
+
/**
|
|
541
|
+
* The union of {@link COLLISION_EVENT_MODES_2D}.
|
|
542
|
+
*
|
|
543
|
+
* @public
|
|
544
|
+
*/
|
|
545
|
+
type CollisionEventMode2D = (typeof COLLISION_EVENT_MODES_2D)[number];
|
|
546
|
+
/**
|
|
547
|
+
* The Rapier objects a `Rigidbody2D` owns. Unstable escape hatch
|
|
548
|
+
* (`docs/architecture/00-overview.md` §3).
|
|
549
|
+
*
|
|
550
|
+
* @public
|
|
551
|
+
*/
|
|
552
|
+
interface Rigidbody2DRapierHandles {
|
|
553
|
+
/** The Rapier body, or `null` before the first fixed step has built it. */
|
|
554
|
+
readonly body: RapierBody | null;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Makes an entity's 2D colliders a Rapier body.
|
|
558
|
+
*
|
|
559
|
+
* @example
|
|
560
|
+
* ```ts
|
|
561
|
+
* const crate = world.createEntity("Crate");
|
|
562
|
+
* crate.transform.position2D = new Vec2(0, 5);
|
|
563
|
+
* crate.addComponent(BoxCollider2D, { size: { x: 1, y: 1 } });
|
|
564
|
+
* crate.addComponent(Rigidbody2D, { mass: 2 });
|
|
565
|
+
* ```
|
|
566
|
+
*
|
|
567
|
+
* @public
|
|
568
|
+
*/
|
|
569
|
+
export declare class Rigidbody2D extends Component implements ComponentHooks {
|
|
570
|
+
#private;
|
|
571
|
+
/** The namespaced registration id. */
|
|
572
|
+
static typeId: string;
|
|
573
|
+
/** One body per entity. */
|
|
574
|
+
static allowMultiple: boolean;
|
|
575
|
+
/** The serialized field declarations (ADR-0004). */
|
|
576
|
+
static schema: Schema;
|
|
577
|
+
bodyType: BodyType2D;
|
|
578
|
+
mass: number;
|
|
579
|
+
gravityScale: number;
|
|
580
|
+
linearDamping: number;
|
|
581
|
+
angularDamping: number;
|
|
582
|
+
freezeRotation: boolean;
|
|
583
|
+
interpolation: InterpolationMode2D;
|
|
584
|
+
collisionEvents: CollisionEventMode2D;
|
|
585
|
+
/** Applies the schema defaults, exactly as `Component.define` would. */
|
|
586
|
+
constructor();
|
|
587
|
+
/** Marks the entity's body for a rebuild at the start of the next fixed step. */
|
|
588
|
+
onAttach(): void;
|
|
589
|
+
/** Marks the entity's body for a rebuild, which turns it back into an implicit static body. */
|
|
590
|
+
onDetach(): void;
|
|
591
|
+
/**
|
|
592
|
+
* Rebuilds the body at the start of the next fixed step. Call it after changing `bodyType`,
|
|
593
|
+
* `mass`, `freezeRotation`, damping, or the entity's scale.
|
|
594
|
+
*/
|
|
595
|
+
rebuild(): void;
|
|
596
|
+
/**
|
|
597
|
+
* The Rapier handles this component owns.
|
|
598
|
+
*
|
|
599
|
+
* @returns The body, or `null` before the first fixed step built it.
|
|
600
|
+
*/
|
|
601
|
+
get rapier(): Rigidbody2DRapierHandles;
|
|
602
|
+
/**
|
|
603
|
+
* The body's linear velocity in metres per second.
|
|
604
|
+
*
|
|
605
|
+
* @returns A freshly allocated vector; use {@link Rigidbody2D.linearVelocityToRef} in hot code.
|
|
606
|
+
*/
|
|
607
|
+
get linearVelocity(): Vec2;
|
|
608
|
+
/**
|
|
609
|
+
* Replaces the body's linear velocity.
|
|
610
|
+
*
|
|
611
|
+
* @param value - Metres per second, world space.
|
|
612
|
+
*/
|
|
613
|
+
set linearVelocity(value: Vec2Like);
|
|
614
|
+
/**
|
|
615
|
+
* Reads the linear velocity without allocating.
|
|
616
|
+
*
|
|
617
|
+
* @param out - The vector to write.
|
|
618
|
+
* @returns `out`.
|
|
619
|
+
*/
|
|
620
|
+
linearVelocityToRef(out: MutableVec2): MutableVec2;
|
|
621
|
+
/**
|
|
622
|
+
* The body's angular velocity.
|
|
623
|
+
*
|
|
624
|
+
* @returns Degrees per second, counter-clockwise — the same unit as `Transform.rotation2D`.
|
|
625
|
+
*/
|
|
626
|
+
get angularVelocity(): number;
|
|
627
|
+
/**
|
|
628
|
+
* Replaces the body's angular velocity.
|
|
629
|
+
*
|
|
630
|
+
* @param value - Degrees per second, counter-clockwise.
|
|
631
|
+
*/
|
|
632
|
+
set angularVelocity(value: number);
|
|
633
|
+
/**
|
|
634
|
+
* The mass Rapier computed for the body, in kilograms.
|
|
635
|
+
*
|
|
636
|
+
* @returns The mass, or `0` before the body exists.
|
|
637
|
+
*/
|
|
638
|
+
get computedMass(): number;
|
|
639
|
+
/**
|
|
640
|
+
* Applies a force for one fixed step. Call it from `fixedUpdate`.
|
|
641
|
+
*
|
|
642
|
+
* @param force - Newtons, world space.
|
|
643
|
+
* @param point - Where to apply it; defaults to the centre of mass.
|
|
644
|
+
*
|
|
645
|
+
* @example
|
|
646
|
+
* ```ts
|
|
647
|
+
* fixedUpdate(): void {
|
|
648
|
+
* this.body.addForce({ x: 0, y: 20 });
|
|
649
|
+
* }
|
|
650
|
+
* ```
|
|
651
|
+
*/
|
|
652
|
+
addForce(force: Vec2Like, point?: Vec2Like): void;
|
|
653
|
+
/**
|
|
654
|
+
* Applies an instantaneous impulse.
|
|
655
|
+
*
|
|
656
|
+
* @param impulse - Newton-seconds, world space.
|
|
657
|
+
* @param point - Where to apply it; defaults to the centre of mass.
|
|
658
|
+
*/
|
|
659
|
+
addImpulse(impulse: Vec2Like, point?: Vec2Like): void;
|
|
660
|
+
/**
|
|
661
|
+
* Applies a torque for one fixed step.
|
|
662
|
+
*
|
|
663
|
+
* @param torque - Newton-metres, positive counter-clockwise.
|
|
664
|
+
*/
|
|
665
|
+
addTorque(torque: number): void;
|
|
666
|
+
/**
|
|
667
|
+
* Moves the body without integrating a velocity, and resets the interpolation history so the
|
|
668
|
+
* display pose does not slide across the gap.
|
|
669
|
+
*
|
|
670
|
+
* @param position - The new world position, in metres.
|
|
671
|
+
* @param rotation - The new rotation in degrees counter-clockwise; defaults to the current one.
|
|
672
|
+
*/
|
|
673
|
+
teleport(position: Vec2Like, rotation?: number): void;
|
|
674
|
+
}
|
|
675
|
+
//#endregion
|
|
676
|
+
//#region src/components/character-controller.d.ts
|
|
677
|
+
/**
|
|
678
|
+
* The `CharacterController2D` component (`docs/architecture/11-2d-toolkit.md` §8): Rapier's
|
|
679
|
+
* `KinematicCharacterController` (`control/character_controller.d.ts`) driven from `fixedUpdate`.
|
|
680
|
+
*
|
|
681
|
+
* ## How it is driven
|
|
682
|
+
*
|
|
683
|
+
* Call {@link CharacterController2D.move} from `fixedUpdate`. The requested displacements of one
|
|
684
|
+
* step are summed and handed to Rapier's `computeColliderMovement` by the step system, so two
|
|
685
|
+
* scripts moving the same character compose instead of fighting. Gravity is **not** applied by this
|
|
686
|
+
* component: a bare controller is purely kinematic, exactly as the 3D one is, and the toolkit
|
|
687
|
+
* controller scripts integrate gravity themselves.
|
|
688
|
+
*
|
|
689
|
+
* After the step the controller owns the entity's world X and Y. Z and `rotation2D` stay
|
|
690
|
+
* user-controlled.
|
|
691
|
+
*
|
|
692
|
+
* ## The one addition to §8: `shape`
|
|
693
|
+
*
|
|
694
|
+
* §8 describes the controller as a capsule. Measured against `@dimforge/rapier2d-compat@0.20.0`
|
|
695
|
+
* (spike S6.2), Rapier's autostep clears a 0.3 m step with a **box** character and refuses anything
|
|
696
|
+
* above about 0.15 m with a capsule of radius 0.2 — so `stepOffset` is only usable with a box.
|
|
697
|
+
* {@link CharacterController2D.shape} therefore chooses between the two, defaulting to `"capsule"`
|
|
698
|
+
* as §8 says, and the limitation is documented in the skill and in ADR-0006's validation section.
|
|
699
|
+
*/
|
|
700
|
+
/**
|
|
701
|
+
* The collision shape a 2D character controller uses.
|
|
702
|
+
*
|
|
703
|
+
* @public
|
|
704
|
+
*/
|
|
705
|
+
export declare const CHARACTER_SHAPES_2D: readonly ["capsule", "box"];
|
|
706
|
+
/**
|
|
707
|
+
* The union of {@link CHARACTER_SHAPES_2D}.
|
|
708
|
+
*
|
|
709
|
+
* @public
|
|
710
|
+
*/
|
|
711
|
+
type CharacterShape2D = (typeof CHARACTER_SHAPES_2D)[number];
|
|
712
|
+
/**
|
|
713
|
+
* A kinematic character that walks, slides, climbs slopes, and steps up.
|
|
714
|
+
*
|
|
715
|
+
* @example
|
|
716
|
+
* ```ts
|
|
717
|
+
* class Walk extends Script implements ScriptCallbacks {
|
|
718
|
+
* static typeId = "mygame/Walk";
|
|
719
|
+
* fixedUpdate(dt: number): void {
|
|
720
|
+
* const controller = this.entity.requireComponent(CharacterController2D);
|
|
721
|
+
* controller.move({ x: 4 * dt, y: -9.81 * dt });
|
|
722
|
+
* }
|
|
723
|
+
* }
|
|
724
|
+
* ```
|
|
725
|
+
*
|
|
726
|
+
* @public
|
|
727
|
+
*/
|
|
728
|
+
export declare class CharacterController2D extends Component implements ComponentHooks {
|
|
729
|
+
#private;
|
|
730
|
+
/** The namespaced registration id. */
|
|
731
|
+
static typeId: string;
|
|
732
|
+
/** One controller per entity. */
|
|
733
|
+
static allowMultiple: boolean;
|
|
734
|
+
/** The serialized field declarations (ADR-0004). */
|
|
735
|
+
static schema: Schema;
|
|
736
|
+
shape: CharacterShape2D;
|
|
737
|
+
radius: number;
|
|
738
|
+
height: number;
|
|
739
|
+
offset: Vec2Like;
|
|
740
|
+
slopeLimit: number;
|
|
741
|
+
stepOffset: number;
|
|
742
|
+
snapToGround: number;
|
|
743
|
+
skinWidth: number;
|
|
744
|
+
onOneWayPlatforms: boolean;
|
|
745
|
+
pushBodies: boolean;
|
|
746
|
+
interpolation: InterpolationMode2D;
|
|
747
|
+
/** Applies the schema defaults. */
|
|
748
|
+
constructor();
|
|
749
|
+
/** Creates the Rapier controller at the start of the next fixed step. */
|
|
750
|
+
onAttach(): void;
|
|
751
|
+
/** Releases the Rapier controller and its collider. */
|
|
752
|
+
onDetach(): void;
|
|
753
|
+
/** Rebuilds the capsule or box at the start of the next fixed step. */
|
|
754
|
+
rebuild(): void;
|
|
755
|
+
/**
|
|
756
|
+
* Requests a displacement for this fixed step. Displacements accumulate until the step runs.
|
|
757
|
+
*
|
|
758
|
+
* @param displacement - The world-space displacement to attempt, in metres.
|
|
759
|
+
*/
|
|
760
|
+
move(displacement: Vec2Like): void;
|
|
761
|
+
/**
|
|
762
|
+
* How fast the character actually moved over the last fixed step, after sliding and blocking.
|
|
763
|
+
*
|
|
764
|
+
* @returns A freshly allocated vector in metres per second.
|
|
765
|
+
*/
|
|
766
|
+
get velocity(): Vec2;
|
|
767
|
+
/**
|
|
768
|
+
* Whether the character ended the last step on walkable ground.
|
|
769
|
+
*
|
|
770
|
+
* @returns Rapier's `computedGrounded` from the last move.
|
|
771
|
+
*/
|
|
772
|
+
get isGrounded(): boolean;
|
|
773
|
+
/**
|
|
774
|
+
* The most upward-facing normal of the obstacles the last move touched.
|
|
775
|
+
*
|
|
776
|
+
* @returns A live view; copy it if you keep it.
|
|
777
|
+
*/
|
|
778
|
+
get groundNormal(): Vec2;
|
|
779
|
+
/**
|
|
780
|
+
* Emitted once per obstacle the character hit during a step.
|
|
781
|
+
*
|
|
782
|
+
* @returns The signal, created on first access.
|
|
783
|
+
*/
|
|
784
|
+
get onCollided(): Signal<CharacterCollision2D>;
|
|
785
|
+
/**
|
|
786
|
+
* Teleports the character, clearing any pending motion and the interpolation history.
|
|
787
|
+
*
|
|
788
|
+
* @param position - The new world position of the entity, in metres.
|
|
789
|
+
*/
|
|
790
|
+
teleport(position: Vec2Like): void;
|
|
791
|
+
/**
|
|
792
|
+
* The displacement requested so far this step, consumed by the step system.
|
|
793
|
+
*
|
|
794
|
+
* @returns A live view of the accumulator.
|
|
795
|
+
*
|
|
796
|
+
* @internal
|
|
797
|
+
*/
|
|
798
|
+
takePendingMove(): Vec2;
|
|
799
|
+
/**
|
|
800
|
+
* Records the outcome of a step.
|
|
801
|
+
*
|
|
802
|
+
* @param movement - What Rapier resolved.
|
|
803
|
+
* @param grounded - Whether the character ended on walkable ground.
|
|
804
|
+
* @param normal - The most upward-facing contact normal, or `null` when there was none.
|
|
805
|
+
* @param deltaSeconds - The fixed step the move covered.
|
|
806
|
+
*
|
|
807
|
+
* @internal
|
|
808
|
+
*/
|
|
809
|
+
applyStepResult(movement: Vec2Like, grounded: boolean, normal: Vec2Like | null, deltaSeconds: number): void;
|
|
810
|
+
/**
|
|
811
|
+
* Emits `onCollided` if anything is listening.
|
|
812
|
+
*
|
|
813
|
+
* @param collision - The obstacle to report.
|
|
814
|
+
*
|
|
815
|
+
* @internal
|
|
816
|
+
*/
|
|
817
|
+
reportHit(collision: CharacterCollision2D): void;
|
|
818
|
+
}
|
|
819
|
+
//#endregion
|
|
820
|
+
//#region src/components/colliders.d.ts
|
|
821
|
+
/**
|
|
822
|
+
* The axis a 2D capsule stands along.
|
|
823
|
+
*
|
|
824
|
+
* @public
|
|
825
|
+
*/
|
|
826
|
+
export declare const CAPSULE_DIRECTIONS_2D: readonly ["x", "y"];
|
|
827
|
+
/**
|
|
828
|
+
* The union of {@link CAPSULE_DIRECTIONS_2D}.
|
|
829
|
+
*
|
|
830
|
+
* @public
|
|
831
|
+
*/
|
|
832
|
+
type CapsuleDirection2D = (typeof CAPSULE_DIRECTIONS_2D)[number];
|
|
833
|
+
/**
|
|
834
|
+
* An axis-aligned box collider, sized in local metres.
|
|
835
|
+
*
|
|
836
|
+
* @example
|
|
837
|
+
* ```ts
|
|
838
|
+
* const floor = world.createEntity("Floor");
|
|
839
|
+
* floor.addComponent(BoxCollider2D, { size: { x: 20, y: 1 } });
|
|
840
|
+
* ```
|
|
841
|
+
*
|
|
842
|
+
* @public
|
|
843
|
+
*/
|
|
844
|
+
export declare class BoxCollider2D extends Collider2D {
|
|
845
|
+
/** The namespaced registration id. */
|
|
846
|
+
static typeId: string;
|
|
847
|
+
/** The serialized field declarations (ADR-0004). */
|
|
848
|
+
static schema: Schema;
|
|
849
|
+
size: Vec2Like;
|
|
850
|
+
/** Applies this collider's defaults on top of the shared ones. */
|
|
851
|
+
constructor();
|
|
852
|
+
/**
|
|
853
|
+
* Appends this collider's Rapier shape.
|
|
854
|
+
*
|
|
855
|
+
* @param scale - The entity's lossy 2D scale.
|
|
856
|
+
* @param out - The list to append to.
|
|
857
|
+
*
|
|
858
|
+
* @internal
|
|
859
|
+
*/
|
|
860
|
+
collectShapes(scale: Vec2Like, out: CollectedShape2D[]): void;
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* A circle collider. Non-uniform scale is not representable as a circle, so the larger scale axis
|
|
864
|
+
* wins — the same rule Unity applies.
|
|
865
|
+
*
|
|
866
|
+
* @public
|
|
867
|
+
*/
|
|
868
|
+
export declare class CircleCollider2D extends Collider2D {
|
|
869
|
+
/** The namespaced registration id. */
|
|
870
|
+
static typeId: string;
|
|
871
|
+
/** The serialized field declarations. */
|
|
872
|
+
static schema: Schema;
|
|
873
|
+
radius: number;
|
|
874
|
+
/** Applies this collider's defaults on top of the shared ones. */
|
|
875
|
+
constructor();
|
|
876
|
+
/**
|
|
877
|
+
* Appends this collider's Rapier shape.
|
|
878
|
+
*
|
|
879
|
+
* @param scale - The entity's lossy 2D scale.
|
|
880
|
+
* @param out - The list to append to.
|
|
881
|
+
*
|
|
882
|
+
* @internal
|
|
883
|
+
*/
|
|
884
|
+
collectShapes(scale: Vec2Like, out: CollectedShape2D[]): void;
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* A capsule collider: a rectangle with semicircular caps, standing along X or Y.
|
|
888
|
+
*
|
|
889
|
+
* @remarks
|
|
890
|
+
* `height` is the **total** tip-to-tip height, so a capsule shorter than `2 * radius` degenerates to
|
|
891
|
+
* a circle of that radius rather than inverting. Rapier's capsule always stands along Y, so an
|
|
892
|
+
* `x` capsule is expressed by swapping the axes of the half-extents — which means an `x` capsule
|
|
893
|
+
* and a rotated `y` capsule are the same shape.
|
|
894
|
+
*
|
|
895
|
+
* @public
|
|
896
|
+
*/
|
|
897
|
+
export declare class CapsuleCollider2D extends Collider2D {
|
|
898
|
+
/** The namespaced registration id. */
|
|
899
|
+
static typeId: string;
|
|
900
|
+
/** The serialized field declarations. */
|
|
901
|
+
static schema: Schema;
|
|
902
|
+
radius: number;
|
|
903
|
+
height: number;
|
|
904
|
+
direction: CapsuleDirection2D;
|
|
905
|
+
/** Applies this collider's defaults on top of the shared ones. */
|
|
906
|
+
constructor();
|
|
907
|
+
/**
|
|
908
|
+
* Appends this collider's Rapier shape.
|
|
909
|
+
*
|
|
910
|
+
* @param scale - The entity's lossy 2D scale.
|
|
911
|
+
* @param out - The list to append to.
|
|
912
|
+
*
|
|
913
|
+
* @internal
|
|
914
|
+
*/
|
|
915
|
+
collectShapes(scale: Vec2Like, out: CollectedShape2D[]): void;
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* A convex polygon collider, wound in either direction, in local metres.
|
|
919
|
+
*
|
|
920
|
+
* @remarks
|
|
921
|
+
* Rapier builds the **convex hull** of the points, so a concave outline is silently rounded out.
|
|
922
|
+
* Model a concave shape as several `PolygonCollider2D`s on one entity, or as an
|
|
923
|
+
* {@link EdgeCollider2D} when it is an open contour.
|
|
924
|
+
*
|
|
925
|
+
* @public
|
|
926
|
+
*/
|
|
927
|
+
export declare class PolygonCollider2D extends Collider2D {
|
|
928
|
+
/** The namespaced registration id. */
|
|
929
|
+
static typeId: string;
|
|
930
|
+
/** The serialized field declarations. */
|
|
931
|
+
static schema: Schema;
|
|
932
|
+
points: Vec2Like[];
|
|
933
|
+
/** Applies this collider's defaults on top of the shared ones. */
|
|
934
|
+
constructor();
|
|
935
|
+
/**
|
|
936
|
+
* Appends this collider's Rapier shape.
|
|
937
|
+
*
|
|
938
|
+
* @param scale - The entity's lossy 2D scale.
|
|
939
|
+
* @param out - The list to append to.
|
|
940
|
+
* @throws IgnifxError with code `IGX-1156` when fewer than three points are given.
|
|
941
|
+
*
|
|
942
|
+
* @internal
|
|
943
|
+
*/
|
|
944
|
+
collectShapes(scale: Vec2Like, out: CollectedShape2D[]): void;
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* An open chain of line segments — a platformer's ground contour.
|
|
948
|
+
*
|
|
949
|
+
* @public
|
|
950
|
+
*/
|
|
951
|
+
export declare class EdgeCollider2D extends Collider2D {
|
|
952
|
+
/** The namespaced registration id. */
|
|
953
|
+
static typeId: string;
|
|
954
|
+
/** The serialized field declarations. */
|
|
955
|
+
static schema: Schema;
|
|
956
|
+
points: Vec2Like[];
|
|
957
|
+
/** Applies this collider's defaults on top of the shared ones. */
|
|
958
|
+
constructor();
|
|
959
|
+
/**
|
|
960
|
+
* Appends this collider's Rapier shape.
|
|
961
|
+
*
|
|
962
|
+
* @param scale - The entity's lossy 2D scale.
|
|
963
|
+
* @param out - The list to append to.
|
|
964
|
+
* @throws IgnifxError with code `IGX-1156` when fewer than two points are given.
|
|
965
|
+
*
|
|
966
|
+
* @internal
|
|
967
|
+
*/
|
|
968
|
+
collectShapes(scale: Vec2Like, out: CollectedShape2D[]): void;
|
|
969
|
+
}
|
|
970
|
+
//#endregion
|
|
971
|
+
//#region src/components/tilemap-collider.d.ts
|
|
972
|
+
/**
|
|
973
|
+
* `TilemapCollider2D` (`docs/architecture/11-2d-toolkit.md` §2.5, §8): the merged collision surface
|
|
974
|
+
* of a `Tilemap`, turned into Rapier geometry.
|
|
975
|
+
*
|
|
976
|
+
* ## How it reaches the data
|
|
977
|
+
*
|
|
978
|
+
* `@ignifx/2d` is an **optional** peer of `@ignifx/physics-2d` (a physics-only 2D game needs no
|
|
979
|
+
* sprite toolkit), so this component never imports the toolkit as a value — only the
|
|
980
|
+
* `TilemapCollisionData` type. A game, or `@ignifx/2d`'s own tilemap loader, assigns
|
|
981
|
+
* {@link TilemapCollider2D.collisionData}; the runtime compares the data's `version` at the start of
|
|
982
|
+
* every fixed step and rebuilds the shapes when it changes, which is the same moment
|
|
983
|
+
* `Tilemap.onCollisionChanged` fires and needs no signal subscription across the package boundary.
|
|
984
|
+
*
|
|
985
|
+
* ## Why closed polylines rather than polygons
|
|
986
|
+
*
|
|
987
|
+
* A merged run of solid tiles is not convex in general — an L of tiles merges into an L — and
|
|
988
|
+
* Rapier's polygon shape is a **convex hull** (`geometry/shape.d.ts`, `ConvexPolygon`), which would
|
|
989
|
+
* silently fill the notch. A closed `polyline` reproduces the outline exactly and is the shape
|
|
990
|
+
* static level geometry wants; the trade-off is that a polyline is infinitely thin, so a body that
|
|
991
|
+
* starts inside the tilemap is not pushed out.
|
|
992
|
+
*/
|
|
993
|
+
/**
|
|
994
|
+
* The collision surface of a tilemap, as one static body's worth of Rapier shapes.
|
|
995
|
+
*
|
|
996
|
+
* @example
|
|
997
|
+
* ```ts
|
|
998
|
+
* const map = world.createEntity("Map");
|
|
999
|
+
* const collider = map.addComponent(TilemapCollider2D);
|
|
1000
|
+
* collider.collisionData = tilemap.collisionData;
|
|
1001
|
+
* ```
|
|
1002
|
+
*
|
|
1003
|
+
* @public
|
|
1004
|
+
*/
|
|
1005
|
+
export declare class TilemapCollider2D extends Collider2D {
|
|
1006
|
+
#private;
|
|
1007
|
+
/** The namespaced registration id. */
|
|
1008
|
+
static typeId: string;
|
|
1009
|
+
/** The serialized field declarations; the geometry itself comes from the tilemap asset. */
|
|
1010
|
+
static schema: Schema;
|
|
1011
|
+
/** Applies the shared defaults. */
|
|
1012
|
+
constructor();
|
|
1013
|
+
/**
|
|
1014
|
+
* The merged chunk geometry this collider builds shapes from.
|
|
1015
|
+
*
|
|
1016
|
+
* @returns The data, or `null` when none has been supplied.
|
|
1017
|
+
*/
|
|
1018
|
+
get collisionData(): TilemapCollisionData | null;
|
|
1019
|
+
/**
|
|
1020
|
+
* Replaces the tilemap geometry and schedules a rebuild.
|
|
1021
|
+
*
|
|
1022
|
+
* @param value - The merged chunk geometry, or `null` to drop the shapes.
|
|
1023
|
+
*/
|
|
1024
|
+
set collisionData(value: TilemapCollisionData | null);
|
|
1025
|
+
/**
|
|
1026
|
+
* Whether the supplied data has changed since the shapes were built. The runtime polls this once
|
|
1027
|
+
* per fixed step, which is how a tile edit reaches physics without a cross-package subscription.
|
|
1028
|
+
*
|
|
1029
|
+
* @returns `true` when a rebuild is due.
|
|
1030
|
+
*
|
|
1031
|
+
* @internal
|
|
1032
|
+
*/
|
|
1033
|
+
needsRebuild(): boolean;
|
|
1034
|
+
/**
|
|
1035
|
+
* Appends one shape per merged outline and one per one-way edge.
|
|
1036
|
+
*
|
|
1037
|
+
* @param scale - The entity's lossy 2D scale.
|
|
1038
|
+
* @param out - The list to append to.
|
|
1039
|
+
*
|
|
1040
|
+
* @internal
|
|
1041
|
+
*/
|
|
1042
|
+
collectShapes(scale: Vec2Like, out: CollectedShape2D[]): void;
|
|
1043
|
+
}
|
|
1044
|
+
//#endregion
|
|
1045
|
+
//#region src/errors.d.ts
|
|
1046
|
+
/**
|
|
1047
|
+
* The diagnostic codes `@ignifx/physics-2d` owns. 2D physics shares the `11` subsystem range with
|
|
1048
|
+
* the 2D toolkit (`docs/architecture/15-devtools-and-diagnostics.md` §1,
|
|
1049
|
+
* `docs/architecture/11-2d-toolkit.md` §8), so the range is split: `@ignifx/2d` owns
|
|
1050
|
+
* `IGX-1101`–`IGX-1149` and this package owns `IGX-1150` upwards.
|
|
1051
|
+
*
|
|
1052
|
+
* `IGX-1101` is the one exception. `11-2d-toolkit.md` §8 names it by number — "registering both
|
|
1053
|
+
* throws `IGX-1101`" — and only this package can detect the condition, so this package registers
|
|
1054
|
+
* it. An app's error-code registry refuses a duplicate registration
|
|
1055
|
+
* (`packages/core/src/errors/error-code-registry.ts`), so `@ignifx/2d` must not declare it.
|
|
1056
|
+
*/
|
|
1057
|
+
/**
|
|
1058
|
+
* Every diagnostic code `@ignifx/physics-2d` can throw or report.
|
|
1059
|
+
*
|
|
1060
|
+
* @example
|
|
1061
|
+
* ```ts
|
|
1062
|
+
* throw physics2DError(Physics2DErrorCode.queryBeforeStep, "raycast() ran before the first step.", {
|
|
1063
|
+
* context: { query: "raycast" },
|
|
1064
|
+
* });
|
|
1065
|
+
* ```
|
|
1066
|
+
*
|
|
1067
|
+
* @public
|
|
1068
|
+
*/
|
|
1069
|
+
export declare const Physics2DErrorCode: {
|
|
1070
|
+
/** Both `physics()` and `physics2d()` are registered on one world (`11-2d-toolkit.md` §8). */
|
|
1071
|
+
readonly bothPhysicsExtensions: "IGX-1101";
|
|
1072
|
+
/** The Rapier WebAssembly module could not be instantiated. */
|
|
1073
|
+
readonly rapierUnavailable: "IGX-1150";
|
|
1074
|
+
/** An entity with 2D colliders but no `Rigidbody2D` moved after its static body was placed. */
|
|
1075
|
+
readonly movedStaticBody: "IGX-1151";
|
|
1076
|
+
/** A collider's layer index is outside the sixteen Rapier's interaction groups can express. */
|
|
1077
|
+
readonly layerOutOfRange: "IGX-1152";
|
|
1078
|
+
/** A query ran before the first completed fixed step, so Rapier has no broadphase yet. */
|
|
1079
|
+
readonly queryBeforeStep: "IGX-1153";
|
|
1080
|
+
/** A `.physicsmaterial.json` file is not an `ignifx.physicsmaterial` document this build reads. */
|
|
1081
|
+
readonly invalidMaterialFile: "IGX-1154";
|
|
1082
|
+
/** The `physics2d.collisionMatrix` setting names a layer the project does not declare. */
|
|
1083
|
+
readonly unknownLayer: "IGX-1155";
|
|
1084
|
+
/** A collider's geometry is degenerate: too few points, or a hull Rapier refused to build. */
|
|
1085
|
+
readonly colliderGeometryInvalid: "IGX-1156";
|
|
1086
|
+
/** A 2D body was built for an entity that has a parent, whose pose is not world space. */
|
|
1087
|
+
readonly bodyOnChildEntity: "IGX-1157";
|
|
1088
|
+
};
|
|
1089
|
+
/**
|
|
1090
|
+
* The union of the codes the `Physics2DErrorCode` table declares.
|
|
1091
|
+
*
|
|
1092
|
+
* @public
|
|
1093
|
+
*/
|
|
1094
|
+
export type Physics2DErrorCode = (typeof Physics2DErrorCode)[keyof typeof Physics2DErrorCode];
|
|
1095
|
+
/**
|
|
1096
|
+
* The one-line message template of every code, as `ExtensionContext.registerErrorCodes` wants it.
|
|
1097
|
+
*
|
|
1098
|
+
* @public
|
|
1099
|
+
*/
|
|
1100
|
+
export declare const PHYSICS_2D_ERROR_MESSAGES: Readonly<Record<string, string>>;
|
|
1101
|
+
/**
|
|
1102
|
+
* Options accepted by {@link physics2DError}.
|
|
1103
|
+
*
|
|
1104
|
+
* @public
|
|
1105
|
+
*/
|
|
1106
|
+
interface Physics2DErrorOptions {
|
|
1107
|
+
/** Identifiers that locate the failure. */
|
|
1108
|
+
readonly context?: ErrorContext;
|
|
1109
|
+
/** One sentence telling the developer what to do about it. */
|
|
1110
|
+
readonly hint?: string;
|
|
1111
|
+
/** The failure being wrapped, when there is one. */
|
|
1112
|
+
readonly cause?: unknown;
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* Builds an `IgnifxError` carrying one of this package's codes.
|
|
1116
|
+
*
|
|
1117
|
+
* @param code - The code from the `Physics2DErrorCode` table.
|
|
1118
|
+
* @param message - The actionable development sentence.
|
|
1119
|
+
* @param options - Context identifiers, a remedy hint, and the wrapped cause.
|
|
1120
|
+
* @returns The error to throw or to reject with.
|
|
1121
|
+
*
|
|
1122
|
+
* @example
|
|
1123
|
+
* ```ts
|
|
1124
|
+
* throw physics2DError(Physics2DErrorCode.unknownLayer, "physics2d.collisionMatrix names Enemy.", {
|
|
1125
|
+
* context: { layer: "Enemy" },
|
|
1126
|
+
* });
|
|
1127
|
+
* ```
|
|
1128
|
+
*
|
|
1129
|
+
* @public
|
|
1130
|
+
*/
|
|
1131
|
+
export declare function physics2DError(code: Physics2DErrorCode, message: string, options?: Physics2DErrorOptions): IgnifxError;
|
|
1132
|
+
//#endregion
|
|
1133
|
+
//#region src/queries.d.ts
|
|
1134
|
+
/**
|
|
1135
|
+
* The query vocabulary of `app.physics2d` (`docs/architecture/11-2d-toolkit.md` §8,
|
|
1136
|
+
* `09-physics.md` §5).
|
|
1137
|
+
*
|
|
1138
|
+
* Unlike the 3D service, every 2D query is **shape-accurate and identity-carrying**: Rapier's
|
|
1139
|
+
* `castRayAndGetNormal`, `intersectionsWithShape`, and `castShape` all return the `Collider` that
|
|
1140
|
+
* was hit (`pipeline/world.d.ts`), so no bounds index is needed and the corrections `09-physics.md`
|
|
1141
|
+
* §5 records for 3D do not apply here.
|
|
1142
|
+
*/
|
|
1143
|
+
/**
|
|
1144
|
+
* Options every 2D query accepts.
|
|
1145
|
+
*
|
|
1146
|
+
* @public
|
|
1147
|
+
*/
|
|
1148
|
+
interface QueryOptions2D {
|
|
1149
|
+
/** Which layers the query may hit. Defaults to everything. */
|
|
1150
|
+
readonly layerMask?: LayerMask;
|
|
1151
|
+
/** Whether trigger volumes count as hits. Defaults to `false`. */
|
|
1152
|
+
readonly hitTriggers?: boolean;
|
|
1153
|
+
}
|
|
1154
|
+
/**
|
|
1155
|
+
* What a 2D ray or shape query hit.
|
|
1156
|
+
*
|
|
1157
|
+
* @remarks
|
|
1158
|
+
* The object is freshly allocated per hit, so it is safe to keep. `raycastAll` returns a **reused**
|
|
1159
|
+
* array of freshly allocated hits.
|
|
1160
|
+
*
|
|
1161
|
+
* @public
|
|
1162
|
+
*/
|
|
1163
|
+
interface RaycastHit2D {
|
|
1164
|
+
/** The entity that was hit. */
|
|
1165
|
+
readonly entity: Entity;
|
|
1166
|
+
/** The collider that was hit. */
|
|
1167
|
+
readonly collider: Collider2D | null;
|
|
1168
|
+
/** The world-space contact point, in metres. */
|
|
1169
|
+
readonly point: Vec2Like;
|
|
1170
|
+
/** The world-space surface normal. */
|
|
1171
|
+
readonly normal: Vec2Like;
|
|
1172
|
+
/** The distance from the ray origin, in metres. */
|
|
1173
|
+
readonly distance: number;
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* What a 2D shape sweep hit.
|
|
1177
|
+
*
|
|
1178
|
+
* @public
|
|
1179
|
+
*/
|
|
1180
|
+
interface ShapeCastHit2D {
|
|
1181
|
+
/** The entity the swept shape hit. */
|
|
1182
|
+
readonly entity: Entity;
|
|
1183
|
+
/** The collider it hit. */
|
|
1184
|
+
readonly collider: Collider2D | null;
|
|
1185
|
+
/** The world-space contact point on the hit collider. */
|
|
1186
|
+
readonly point: Vec2Like;
|
|
1187
|
+
/** The world-space contact normal. */
|
|
1188
|
+
readonly normal: Vec2Like;
|
|
1189
|
+
/** The distance travelled before contact, in metres. */
|
|
1190
|
+
readonly distance: number;
|
|
1191
|
+
/** How far along the sweep the contact occurs, in `[0, 1]`. */
|
|
1192
|
+
readonly fraction: number;
|
|
1193
|
+
}
|
|
1194
|
+
//#endregion
|
|
1195
|
+
//#region src/runtime/body-record.d.ts
|
|
1196
|
+
/**
|
|
1197
|
+
* One entity's 2D physics representation. The runtime keeps these in creation order, which is the
|
|
1198
|
+
* iteration order every per-step loop uses — body creation order is what decides Rapier's internal
|
|
1199
|
+
* ordering, so keeping it stable is part of determinism (`docs/architecture/09-physics.md` §8).
|
|
1200
|
+
*
|
|
1201
|
+
* @internal
|
|
1202
|
+
*/
|
|
1203
|
+
interface BodyRecord2D {
|
|
1204
|
+
/** The entity the body belongs to. */
|
|
1205
|
+
readonly entity: Entity;
|
|
1206
|
+
/** The `Rigidbody2D`, or `null` for an implicit static body or a bare controller. */
|
|
1207
|
+
rigidbody: Rigidbody2D | null;
|
|
1208
|
+
/** The `CharacterController2D`, or `null`. */
|
|
1209
|
+
controller: CharacterController2D | null;
|
|
1210
|
+
/** The Rapier body. */
|
|
1211
|
+
body: RapierBody;
|
|
1212
|
+
/** Every Rapier collider the record owns, in creation order. */
|
|
1213
|
+
colliders: RapierCollider[];
|
|
1214
|
+
/** The ignifx collider each Rapier collider came from; `null` for the controller's own shape. */
|
|
1215
|
+
owners: (Collider2D | null)[];
|
|
1216
|
+
/** The controller's own collider, which is what `computeColliderMovement` moves. */
|
|
1217
|
+
controllerCollider: RapierCollider | null;
|
|
1218
|
+
/** How the body moves. */
|
|
1219
|
+
motion: BodyMotion2D;
|
|
1220
|
+
/** Whether the display pose is interpolated between fixed steps. */
|
|
1221
|
+
interpolate: boolean;
|
|
1222
|
+
/** The layer the filter word was built from, so a runtime change is noticed. */
|
|
1223
|
+
layer: number;
|
|
1224
|
+
/** Whether the record's colliders currently raise events. */
|
|
1225
|
+
collisionEvents: boolean;
|
|
1226
|
+
/** The position at the end of the previous fixed step. */
|
|
1227
|
+
readonly previousPosition: Vec2;
|
|
1228
|
+
/** The rotation in radians at the end of the previous fixed step. */
|
|
1229
|
+
previousRotation: number;
|
|
1230
|
+
/** The authoritative position at the end of the last fixed step. */
|
|
1231
|
+
readonly currentPosition: Vec2;
|
|
1232
|
+
/** The authoritative rotation in radians at the end of the last fixed step. */
|
|
1233
|
+
currentRotation: number;
|
|
1234
|
+
/**
|
|
1235
|
+
* The linear velocity as it was *before* the last step's solver ran, which is the impact speed a
|
|
1236
|
+
* collision callback wants — reading it afterwards reports the resolved velocity, which for a
|
|
1237
|
+
* landing body is zero.
|
|
1238
|
+
*/
|
|
1239
|
+
readonly preStepVelocity: Vec2;
|
|
1240
|
+
/** `Transform.worldMatrixVersion` when an implicit static body was placed (`IGX-1151`). */
|
|
1241
|
+
staticVersion: number;
|
|
1242
|
+
/** Whether the `IGX-1151` diagnostic has already been reported for this body. */
|
|
1243
|
+
reportedMove: boolean;
|
|
1244
|
+
/** Signal connections the record owns, dropped when it is torn down. */
|
|
1245
|
+
disconnects: Disconnect[];
|
|
1246
|
+
}
|
|
1247
|
+
//#endregion
|
|
1248
|
+
//#region src/runtime/runtime.d.ts
|
|
1249
|
+
/**
|
|
1250
|
+
* The per-app 2D physics runtime: the Rapier world, the bodies, the character controllers, the
|
|
1251
|
+
* event drain, and the three things the systems ask it to do each frame — restore, step,
|
|
1252
|
+
* interpolate (`docs/architecture/11-2d-toolkit.md` §8, `09-physics.md` §1).
|
|
1253
|
+
*
|
|
1254
|
+
* Everything here is `@internal`; the public surface is `Physics2DService`, `Rigidbody2D`, the 2D
|
|
1255
|
+
* colliders, and `CharacterController2D`.
|
|
1256
|
+
*/
|
|
1257
|
+
/** What the extension hands the runtime. */
|
|
1258
|
+
interface Physics2DRuntimeOptions {
|
|
1259
|
+
/** The extension registration surface; the physics kernel hooks live on it. */
|
|
1260
|
+
readonly ctx: ExtensionContext;
|
|
1261
|
+
/** The resolved `physics2d` settings section. */
|
|
1262
|
+
readonly settings: Physics2DSettings;
|
|
1263
|
+
/** The Rapier world. */
|
|
1264
|
+
readonly world: RapierWorld;
|
|
1265
|
+
/** The `physics2d` diagnostics group. */
|
|
1266
|
+
readonly counters: DiagnosticsGroup;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* The counters `09-physics.md` §9 and `11-2d-toolkit.md` §8 name for 2D.
|
|
1270
|
+
*
|
|
1271
|
+
* @public
|
|
1272
|
+
*/
|
|
1273
|
+
export declare const PHYSICS_2D_DIAGNOSTICS_COUNTERS: readonly string[];
|
|
1274
|
+
/**
|
|
1275
|
+
* The diagnostics group name.
|
|
1276
|
+
*
|
|
1277
|
+
* @public
|
|
1278
|
+
*/
|
|
1279
|
+
export declare const PHYSICS_2D_DIAGNOSTICS_GROUP = "physics2d";
|
|
1280
|
+
/** Which ignifx collider a Rapier collider belongs to. */
|
|
1281
|
+
interface ColliderBinding {
|
|
1282
|
+
/** The record that owns it. */
|
|
1283
|
+
readonly record: BodyRecord2D;
|
|
1284
|
+
/** The authored collider, or `null` for a character controller's own shape. */
|
|
1285
|
+
readonly owner: Collider2D | null;
|
|
1286
|
+
/** The Rapier collider itself, which the event and contact paths need. */
|
|
1287
|
+
readonly collider: RapierCollider;
|
|
1288
|
+
}
|
|
1289
|
+
/**
|
|
1290
|
+
* The per-app 2D physics runtime.
|
|
1291
|
+
*
|
|
1292
|
+
* @internal
|
|
1293
|
+
*/
|
|
1294
|
+
declare class Physics2DRuntime {
|
|
1295
|
+
#private;
|
|
1296
|
+
/**
|
|
1297
|
+
* Builds the runtime and applies the world settings.
|
|
1298
|
+
*
|
|
1299
|
+
* @param options - The context, settings, world, and counters.
|
|
1300
|
+
* @throws IgnifxError with code `IGX-1155` when the collision matrix names an unknown layer.
|
|
1301
|
+
*/
|
|
1302
|
+
constructor(options: Physics2DRuntimeOptions);
|
|
1303
|
+
/**
|
|
1304
|
+
* The Rapier world, for the query and escape-hatch paths.
|
|
1305
|
+
*
|
|
1306
|
+
* @returns The world handle.
|
|
1307
|
+
*/
|
|
1308
|
+
get world(): RapierWorld;
|
|
1309
|
+
/**
|
|
1310
|
+
* Whether at least one fixed step has run, which is what Rapier's broadphase needs before a query
|
|
1311
|
+
* can answer (`09-physics.md` §5, spike S6.2).
|
|
1312
|
+
*
|
|
1313
|
+
* @returns `true` once a step has completed.
|
|
1314
|
+
*/
|
|
1315
|
+
get hasStepped(): boolean;
|
|
1316
|
+
/**
|
|
1317
|
+
* Every body, in creation order.
|
|
1318
|
+
*
|
|
1319
|
+
* @returns The records.
|
|
1320
|
+
*/
|
|
1321
|
+
get records(): readonly BodyRecord2D[];
|
|
1322
|
+
/**
|
|
1323
|
+
* The resolved settings.
|
|
1324
|
+
*
|
|
1325
|
+
* @returns The `physics2d` section.
|
|
1326
|
+
*/
|
|
1327
|
+
get settings(): Physics2DSettings;
|
|
1328
|
+
/**
|
|
1329
|
+
* Replaces world gravity.
|
|
1330
|
+
*
|
|
1331
|
+
* @param gravity - The new acceleration vector.
|
|
1332
|
+
*/
|
|
1333
|
+
setGravity(gravity: Vec2Like): void;
|
|
1334
|
+
/**
|
|
1335
|
+
* Marks an entity's body for a rebuild at the start of the next fixed step.
|
|
1336
|
+
*
|
|
1337
|
+
* @param entity - The entity whose colliders, `Rigidbody2D`, or controller changed.
|
|
1338
|
+
*/
|
|
1339
|
+
markDirty(entity: Entity): void;
|
|
1340
|
+
/**
|
|
1341
|
+
* Marks a character controller's entity for a rebuild.
|
|
1342
|
+
*
|
|
1343
|
+
* @param component - The controller component.
|
|
1344
|
+
*/
|
|
1345
|
+
markControllerDirty(component: CharacterController2D): void;
|
|
1346
|
+
/**
|
|
1347
|
+
* Drops a character controller's body, which is what detaching the component does.
|
|
1348
|
+
*
|
|
1349
|
+
* @param component - The controller component.
|
|
1350
|
+
*/
|
|
1351
|
+
releaseController(component: CharacterController2D): void;
|
|
1352
|
+
/**
|
|
1353
|
+
* The Rapier body of an entity, for the escape hatch.
|
|
1354
|
+
*
|
|
1355
|
+
* @param entity - The entity.
|
|
1356
|
+
* @returns The body handle, or `null`.
|
|
1357
|
+
*/
|
|
1358
|
+
bodyHandleOf(entity: Entity): BodyRecord2D["body"] | null;
|
|
1359
|
+
/**
|
|
1360
|
+
* The record an entity owns.
|
|
1361
|
+
*
|
|
1362
|
+
* @param entity - The entity.
|
|
1363
|
+
* @returns The record, or `null`.
|
|
1364
|
+
*/
|
|
1365
|
+
recordOf(entity: Entity): BodyRecord2D | null;
|
|
1366
|
+
/**
|
|
1367
|
+
* The entity and collider a Rapier collider belongs to, which is how a query result or an event
|
|
1368
|
+
* becomes an ignifx object.
|
|
1369
|
+
*
|
|
1370
|
+
* @param collider - The Rapier collider, or `null`.
|
|
1371
|
+
* @returns The binding, or `null`.
|
|
1372
|
+
*/
|
|
1373
|
+
bindingOf(collider: RapierCollider | null): ColliderBinding | null;
|
|
1374
|
+
/**
|
|
1375
|
+
* The mass Rapier computed for an entity's body.
|
|
1376
|
+
*
|
|
1377
|
+
* @param entity - The entity.
|
|
1378
|
+
* @returns Kilograms, or `0` when there is no body.
|
|
1379
|
+
*/
|
|
1380
|
+
massOf(entity: Entity): number;
|
|
1381
|
+
/**
|
|
1382
|
+
* Reads a body's linear velocity.
|
|
1383
|
+
*
|
|
1384
|
+
* @param entity - The entity.
|
|
1385
|
+
* @param out - The vector to write; left untouched when there is no body.
|
|
1386
|
+
*/
|
|
1387
|
+
readLinear(entity: Entity, out: MutableVec2): void;
|
|
1388
|
+
/**
|
|
1389
|
+
* Reads a body's angular velocity.
|
|
1390
|
+
*
|
|
1391
|
+
* @param entity - The entity.
|
|
1392
|
+
* @returns Degrees per second, counter-clockwise.
|
|
1393
|
+
*/
|
|
1394
|
+
readAngular(entity: Entity): number;
|
|
1395
|
+
/**
|
|
1396
|
+
* Sets a body's linear velocity.
|
|
1397
|
+
*
|
|
1398
|
+
* @param entity - The entity.
|
|
1399
|
+
* @param velocity - Metres per second.
|
|
1400
|
+
*/
|
|
1401
|
+
setLinearVelocity(entity: Entity, velocity: Vec2Like): void;
|
|
1402
|
+
/**
|
|
1403
|
+
* Sets a body's angular velocity.
|
|
1404
|
+
*
|
|
1405
|
+
* @param entity - The entity.
|
|
1406
|
+
* @param velocity - Degrees per second.
|
|
1407
|
+
*/
|
|
1408
|
+
setAngularVelocity(entity: Entity, velocity: number): void;
|
|
1409
|
+
/**
|
|
1410
|
+
* Applies a force for one fixed step.
|
|
1411
|
+
*
|
|
1412
|
+
* @param entity - The entity.
|
|
1413
|
+
* @param force - Newtons.
|
|
1414
|
+
* @param point - The application point, or `null` for the centre of mass.
|
|
1415
|
+
*/
|
|
1416
|
+
addForce(entity: Entity, force: Vec2Like, point: Vec2Like | null): void;
|
|
1417
|
+
/**
|
|
1418
|
+
* Applies an impulse.
|
|
1419
|
+
*
|
|
1420
|
+
* @param entity - The entity.
|
|
1421
|
+
* @param impulse - Newton-seconds.
|
|
1422
|
+
* @param point - The application point, or `null` for the centre of mass.
|
|
1423
|
+
*/
|
|
1424
|
+
addImpulse(entity: Entity, impulse: Vec2Like, point: Vec2Like | null): void;
|
|
1425
|
+
/**
|
|
1426
|
+
* Applies a torque for one fixed step.
|
|
1427
|
+
*
|
|
1428
|
+
* @param entity - The entity.
|
|
1429
|
+
* @param torque - Newton-metres, positive counter-clockwise.
|
|
1430
|
+
*/
|
|
1431
|
+
addTorque(entity: Entity, torque: number): void;
|
|
1432
|
+
/**
|
|
1433
|
+
* Teleports a body and resets its interpolation history.
|
|
1434
|
+
*
|
|
1435
|
+
* @param entity - The entity.
|
|
1436
|
+
* @param position - The new world position.
|
|
1437
|
+
* @param rotationDegrees - The new rotation in degrees counter-clockwise.
|
|
1438
|
+
*/
|
|
1439
|
+
teleport(entity: Entity, position: Vec2Like, rotationDegrees: number): void;
|
|
1440
|
+
/**
|
|
1441
|
+
* Teleports a character controller.
|
|
1442
|
+
*
|
|
1443
|
+
* @param component - The controller component.
|
|
1444
|
+
* @param position - The new world position.
|
|
1445
|
+
*/
|
|
1446
|
+
teleportController(component: CharacterController2D, position: Vec2Like): void;
|
|
1447
|
+
/**
|
|
1448
|
+
* Restores the authoritative pose of every interpolated body, undoing the display pose the
|
|
1449
|
+
* `PreRender` system wrote (`09-physics.md` §1).
|
|
1450
|
+
*/
|
|
1451
|
+
restorePoses(): void;
|
|
1452
|
+
/**
|
|
1453
|
+
* Runs one fixed step: reconcile, push kinematic poses, move controllers, step Rapier, snapshot,
|
|
1454
|
+
* dispatch events.
|
|
1455
|
+
*
|
|
1456
|
+
* @param fixedDeltaSeconds - The fixed step in seconds.
|
|
1457
|
+
*/
|
|
1458
|
+
step(fixedDeltaSeconds: number): void;
|
|
1459
|
+
/**
|
|
1460
|
+
* Writes the interpolated display pose of every interpolated body.
|
|
1461
|
+
*
|
|
1462
|
+
* @param alpha - `time.fixedStepAlpha`, in `[0, 1)`.
|
|
1463
|
+
*/
|
|
1464
|
+
interpolate(alpha: number): void;
|
|
1465
|
+
/** Tears every body down and releases the Rapier world. */
|
|
1466
|
+
dispose(): void;
|
|
1467
|
+
}
|
|
1468
|
+
//#endregion
|
|
1469
|
+
//#region src/runtime/host.d.ts
|
|
1470
|
+
/**
|
|
1471
|
+
* The one mutable cell between `register` and `onStart`.
|
|
1472
|
+
*
|
|
1473
|
+
* `Extension.register` runs **before** `createApp` builds the world
|
|
1474
|
+
* (`packages/core/src/app/app.ts`, `initialize`), and the Rapier world needs the world's layer
|
|
1475
|
+
* table and Rapier's WebAssembly module, which is loaded asynchronously. So the extension declares
|
|
1476
|
+
* its systems and its service in `register` — which is where `docs/architecture/04-extensions.md`
|
|
1477
|
+
* §1 says everything is declared — and they all read the runtime through this holder, which
|
|
1478
|
+
* `onStart` fills in.
|
|
1479
|
+
*
|
|
1480
|
+
* @internal
|
|
1481
|
+
*/
|
|
1482
|
+
declare class Physics2DHost {
|
|
1483
|
+
/** The runtime, or `null` until `onStart` has built it. */
|
|
1484
|
+
runtime: Physics2DRuntime | null;
|
|
1485
|
+
}
|
|
1486
|
+
//#endregion
|
|
1487
|
+
//#region src/service.d.ts
|
|
1488
|
+
/**
|
|
1489
|
+
* The Rapier objects the 2D physics extension owns. Unstable escape hatch
|
|
1490
|
+
* (`docs/architecture/00-overview.md` §3).
|
|
1491
|
+
*
|
|
1492
|
+
* @public
|
|
1493
|
+
*/
|
|
1494
|
+
interface Physics2DRapierHandles {
|
|
1495
|
+
/** Rapier's `World`. */
|
|
1496
|
+
readonly world: RapierWorld;
|
|
1497
|
+
}
|
|
1498
|
+
/**
|
|
1499
|
+
* The service behind `app.physics2d`.
|
|
1500
|
+
*
|
|
1501
|
+
* @example
|
|
1502
|
+
* ```ts
|
|
1503
|
+
* const hit = app.physics2d.raycast({ x: 0, y: 5 }, { x: 0, y: -1 }, 20);
|
|
1504
|
+
* if (hit !== null) {
|
|
1505
|
+
* app.log.info(`ray hit ${hit.entity.name} at ${String(hit.point.y)}`);
|
|
1506
|
+
* }
|
|
1507
|
+
* ```
|
|
1508
|
+
*
|
|
1509
|
+
* @public
|
|
1510
|
+
*/
|
|
1511
|
+
export declare class Physics2DService {
|
|
1512
|
+
#private;
|
|
1513
|
+
/**
|
|
1514
|
+
* Wraps the holder the extension fills in from `onStart`.
|
|
1515
|
+
*
|
|
1516
|
+
* @param host - The holder the runtime lands in.
|
|
1517
|
+
* @param settings - The resolved `physics2d` settings section.
|
|
1518
|
+
*
|
|
1519
|
+
* @internal
|
|
1520
|
+
*/
|
|
1521
|
+
constructor(host: Physics2DHost, settings: Physics2DSettings);
|
|
1522
|
+
/**
|
|
1523
|
+
* World gravity in metres per second squared.
|
|
1524
|
+
*
|
|
1525
|
+
* @returns A live view; writing to it does nothing, assign the property instead.
|
|
1526
|
+
*/
|
|
1527
|
+
get gravity(): Vec2;
|
|
1528
|
+
/**
|
|
1529
|
+
* Replaces world gravity, which every body feels from the next fixed step.
|
|
1530
|
+
*
|
|
1531
|
+
* @param value - The new acceleration vector.
|
|
1532
|
+
*/
|
|
1533
|
+
set gravity(value: Vec2Like);
|
|
1534
|
+
/**
|
|
1535
|
+
* The Rapier handles.
|
|
1536
|
+
*
|
|
1537
|
+
* @returns The world.
|
|
1538
|
+
*/
|
|
1539
|
+
get rapier(): Physics2DRapierHandles;
|
|
1540
|
+
/**
|
|
1541
|
+
* Casts a ray and returns the first entity it hits.
|
|
1542
|
+
*
|
|
1543
|
+
* @param origin - The world-space origin, in metres.
|
|
1544
|
+
* @param direction - The direction; it is normalised for you.
|
|
1545
|
+
* @param maxDistance - How far to travel; defaults to 10 km.
|
|
1546
|
+
* @param options - Layer mask and trigger behaviour.
|
|
1547
|
+
* @returns The hit, or `null` when the ray clears everything.
|
|
1548
|
+
* @throws IgnifxError with code `IGX-1153` when no fixed step has run yet.
|
|
1549
|
+
*/
|
|
1550
|
+
raycast(origin: Vec2Like, direction: Vec2Like, maxDistance?: number, options?: QueryOptions2D): RaycastHit2D | null;
|
|
1551
|
+
/**
|
|
1552
|
+
* Casts a ray and returns every entity along it, nearest first.
|
|
1553
|
+
*
|
|
1554
|
+
* @param origin - The world-space origin.
|
|
1555
|
+
* @param direction - The direction; it is normalised for you.
|
|
1556
|
+
* @param maxDistance - How far to travel; defaults to 10 km.
|
|
1557
|
+
* @param options - Layer mask and trigger behaviour.
|
|
1558
|
+
* @returns The hits, in increasing distance. The array is reused between calls.
|
|
1559
|
+
* @throws IgnifxError with code `IGX-1153` when no fixed step has run yet.
|
|
1560
|
+
*/
|
|
1561
|
+
raycastAll(origin: Vec2Like, direction: Vec2Like, maxDistance?: number, options?: QueryOptions2D): readonly RaycastHit2D[];
|
|
1562
|
+
/**
|
|
1563
|
+
* Lists the entities a circle overlaps.
|
|
1564
|
+
*
|
|
1565
|
+
* @param centre - The circle's world position.
|
|
1566
|
+
* @param radius - Its radius in metres.
|
|
1567
|
+
* @param options - Layer mask and trigger behaviour.
|
|
1568
|
+
* @returns The overlapping entities, in Rapier's order. The array is reused between calls.
|
|
1569
|
+
* @throws IgnifxError with code `IGX-1153` when no fixed step has run yet.
|
|
1570
|
+
*/
|
|
1571
|
+
overlapCircle(centre: Vec2Like, radius: number, options?: QueryOptions2D): readonly Entity[];
|
|
1572
|
+
/**
|
|
1573
|
+
* Lists the entities a box overlaps.
|
|
1574
|
+
*
|
|
1575
|
+
* @param centre - The box's world position.
|
|
1576
|
+
* @param size - Its full width and height in metres.
|
|
1577
|
+
* @param rotation - Its rotation in degrees counter-clockwise; defaults to `0`.
|
|
1578
|
+
* @param options - Layer mask and trigger behaviour.
|
|
1579
|
+
* @returns The overlapping entities. The array is reused between calls.
|
|
1580
|
+
* @throws IgnifxError with code `IGX-1153` when no fixed step has run yet.
|
|
1581
|
+
*/
|
|
1582
|
+
overlapBox(centre: Vec2Like, size: Vec2Like, rotation?: number, options?: QueryOptions2D): readonly Entity[];
|
|
1583
|
+
/**
|
|
1584
|
+
* Sweeps a circle and returns the first contact.
|
|
1585
|
+
*
|
|
1586
|
+
* @param centre - Where the sweep starts.
|
|
1587
|
+
* @param radius - The circle's radius in metres.
|
|
1588
|
+
* @param direction - The sweep direction; it is normalised for you.
|
|
1589
|
+
* @param maxDistance - How far to sweep.
|
|
1590
|
+
* @param options - Layer mask and trigger behaviour.
|
|
1591
|
+
* @returns The hit, or `null`.
|
|
1592
|
+
* @throws IgnifxError with code `IGX-1153` when no fixed step has run yet.
|
|
1593
|
+
*/
|
|
1594
|
+
shapeCast(centre: Vec2Like, radius: number, direction: Vec2Like, maxDistance: number, options?: QueryOptions2D): ShapeCastHit2D | null;
|
|
1595
|
+
}
|
|
1596
|
+
//#endregion
|
|
1597
|
+
//#region src/extension.d.ts
|
|
1598
|
+
/**
|
|
1599
|
+
* The `@ignifx/physics-2d` extension (`docs/architecture/11-2d-toolkit.md` §8,
|
|
1600
|
+
* `04-extensions.md` §1).
|
|
1601
|
+
*
|
|
1602
|
+
* ## Why `@ignifx/2d` is optional rather than required
|
|
1603
|
+
*
|
|
1604
|
+
* `00-overview.md` §2 draws `@ignifx/physics-2d` above `@ignifx/2d`, and the layering rule allows
|
|
1605
|
+
* the dependency. At runtime the only thing this package needs from the toolkit is the
|
|
1606
|
+
* `TilemapCollisionData` **type**, which is erased at build time, so a platformer that draws its own
|
|
1607
|
+
* graphics can register `physics2d()` on its own. The manifest therefore declares
|
|
1608
|
+
* `requires: []` and `optional: ["@ignifx/2d"]`, and `package.json` makes `@ignifx/2d` an optional
|
|
1609
|
+
* peer dependency.
|
|
1610
|
+
*
|
|
1611
|
+
* ## Why the world is built in `onStart`
|
|
1612
|
+
*
|
|
1613
|
+
* `register` runs before `createApp` builds the `World` (`packages/core/src/app/app.ts`,
|
|
1614
|
+
* `initialize`), and the Rapier world needs the world's layer table; Rapier's WebAssembly module
|
|
1615
|
+
* also has to be instantiated, which is asynchronous. So `register` declares everything against a
|
|
1616
|
+
* {@link Physics2DHost} holder and `onStart` fills the holder in.
|
|
1617
|
+
*
|
|
1618
|
+
* ## One physics extension per world
|
|
1619
|
+
*
|
|
1620
|
+
* `11-2d-toolkit.md` §8: "A world uses either `physics()` or `physics2d()`; registering both throws
|
|
1621
|
+
* `IGX-1101`". `@ignifx/physics` publishes its Havok simulation scene through
|
|
1622
|
+
* `ExtensionContext.setSimulationScene`, so `app.world.lite.simulationScene !== null` at `onStart`
|
|
1623
|
+
* is the test — and it needs no dependency on `@ignifx/physics`, which this package must not have.
|
|
1624
|
+
*/
|
|
1625
|
+
/**
|
|
1626
|
+
* What `physics2d()` accepts.
|
|
1627
|
+
*
|
|
1628
|
+
* @public
|
|
1629
|
+
*/
|
|
1630
|
+
interface Physics2DOptions {
|
|
1631
|
+
/**
|
|
1632
|
+
* Replaces the step that instantiates Rapier's WebAssembly module. The default awaits
|
|
1633
|
+
* `RAPIER.init()`, which decodes the base64 payload the `-compat` build inlines; a host that has
|
|
1634
|
+
* already preloaded the module, or a test that wants to observe the failure path, supplies its
|
|
1635
|
+
* own.
|
|
1636
|
+
*/
|
|
1637
|
+
readonly initialize?: () => Promise<void>;
|
|
1638
|
+
}
|
|
1639
|
+
declare module "@ignifx/core" {
|
|
1640
|
+
interface App {
|
|
1641
|
+
/** 2D physics: gravity, queries, and the Rapier escape hatch. */
|
|
1642
|
+
readonly physics2d: Physics2DService;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
/**
|
|
1646
|
+
* Builds the 2D physics extension.
|
|
1647
|
+
*
|
|
1648
|
+
* @param options - Optionally, an already-instantiated Rapier module.
|
|
1649
|
+
* @returns The extension descriptor.
|
|
1650
|
+
*
|
|
1651
|
+
* @example
|
|
1652
|
+
* ```ts
|
|
1653
|
+
* const app = await createApp({ headless: true, extensions: [physics2d()] });
|
|
1654
|
+
* ```
|
|
1655
|
+
*
|
|
1656
|
+
* @public
|
|
1657
|
+
*/
|
|
1658
|
+
export declare const physics2d: (options?: Physics2DOptions) => Extension;
|
|
1659
|
+
//#endregion
|
|
1660
|
+
//#region src/schemas.d.ts
|
|
1661
|
+
/**
|
|
1662
|
+
* The documentation harness's view of everything `@ignifx/physics-2d` declares
|
|
1663
|
+
* (`docs/architecture/16-docs-harness-and-skill.md` §3, `scripts/README.md`).
|
|
1664
|
+
*
|
|
1665
|
+
* The `ignifx.physicsmaterial` **file format** is deliberately absent: `@ignifx/physics` already
|
|
1666
|
+
* documents it and this package reads the very same document (`material.ts`), so describing it
|
|
1667
|
+
* twice would render the same table on the formats page twice — the harness keeps the first
|
|
1668
|
+
* declaration and drops the rest (`scripts/lib/schema-source.ts`).
|
|
1669
|
+
*/
|
|
1670
|
+
/**
|
|
1671
|
+
* Describes every component this package declares.
|
|
1672
|
+
*
|
|
1673
|
+
* @returns The records, keyed by namespaced type id.
|
|
1674
|
+
*
|
|
1675
|
+
* @example
|
|
1676
|
+
* ```ts
|
|
1677
|
+
* const schemas = describeSchemas();
|
|
1678
|
+
* schemas["ignifx/Rigidbody2D"].fields["mass"].default; // 1
|
|
1679
|
+
* ```
|
|
1680
|
+
*
|
|
1681
|
+
* @public
|
|
1682
|
+
*/
|
|
1683
|
+
export declare function describeSchemas(): Readonly<Record<string, SchemaDescription>>;
|
|
1684
|
+
//#endregion
|
|
1685
|
+
export type { BodyType2D, CapsuleDirection2D, CharacterCollision2D, CharacterShape2D, Collision2D, CollisionEventMode2D, CombineRule, ContactPoint2D, InterpolationMode2D, Physics2DErrorOptions, Physics2DMaterialValues, Physics2DOptions, Physics2DRapierHandles, Physics2DSettings, QueryOptions2D, RaycastHit2D, Rigidbody2DRapierHandles, ShapeCastHit2D, TriggerEvent2D };
|
|
1686
|
+
//# sourceMappingURL=index.d.ts.map
|