Rapier 2D (@dimforge/rapier2d-compat 0.20) comes in as the physics engine: the editor loads it once in the background right after opening a project from its own chunk, so the main bundle grows by 0.19 KB gzip and the first frame does not wait; loadPhysics, physicsStatus and the 100 px = 1 m conversion live in src/runtime/physics/engine.ts, __gm.physics() reports the state, unit tests pin free fall and a box resting on a box, and e2e module 41 pins that Rapier is ready from its own chunk without console noise (#145)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6d7d0005cf
commit
d02bcca266
9 files changed
+143
-1
No files matched your search
@@ -0,0 +1,40 @@
|
||||
import type RAPIER from '@dimforge/rapier2d-compat';
|
||||
|
||||
export type Rapier = typeof RAPIER;
|
||||
|
||||
/** Everything outside the engine is in pixels; Rapier is tuned for metres. */
|
||||
export const PIXELS_PER_METRE = 100;
|
||||
|
||||
export const toMetres = (pixels: number): number => pixels / PIXELS_PER_METRE;
|
||||
export const toPixels = (metres: number): number => metres * PIXELS_PER_METRE;
|
||||
|
||||
export type PhysicsStatus =
|
||||
| { state: 'idle' | 'loading' }
|
||||
| { state: 'ready'; ms: number; version: string }
|
||||
| { state: 'failed'; error: string };
|
||||
|
||||
let status: PhysicsStatus = { state: 'idle' };
|
||||
let loading: Promise<Rapier> | null = null;
|
||||
|
||||
/**
|
||||
* Rapier is its own chunk with the WebAssembly inside. Every caller shares the one load, and a
|
||||
* failed load stays failed rather than being tried again on each call.
|
||||
*/
|
||||
export function loadPhysics(): Promise<Rapier> {
|
||||
if (loading) return loading;
|
||||
const start = performance.now();
|
||||
status = { state: 'loading' };
|
||||
loading = import('@dimforge/rapier2d-compat').then(async ({ default: rapier }) => {
|
||||
await rapier.init();
|
||||
status = { state: 'ready', ms: Math.round(performance.now() - start), version: rapier.version() };
|
||||
return rapier;
|
||||
});
|
||||
loading.catch((error: unknown) => {
|
||||
status = { state: 'failed', error: error instanceof Error ? error.message : String(error) };
|
||||
});
|
||||
return loading;
|
||||
}
|
||||
|
||||
export function physicsStatus(): PhysicsStatus {
|
||||
return status;
|
||||
}
|
||||
Reference in new issue
Block a user