@absolutejs/rapier3d 0.10.0 → 0.12.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.
@@ -5,3 +5,4 @@ export * from "./event_queue";
5
5
  export * from "./physics_hooks";
6
6
  export * from "./debug_render_pipeline";
7
7
  export * from "./query_pipeline";
8
+ export * from "./step_profile";
@@ -0,0 +1,65 @@
1
+ import type { World, ContactConvergenceStats } from "./world";
2
+ import type { EventQueue } from "./event_queue";
3
+ import type { PhysicsHooks } from "./physics_hooks";
4
+ export interface PhysicsStepSample {
5
+ /** Zero-based index among calls made through this recorder. */
6
+ step: number;
7
+ outcome: "completed" | "threw";
8
+ /** Time inside World.step, excluding profile capture and recorder bookkeeping. */
9
+ wallTimeMs: number | null;
10
+ captureStatus: "captured" | "step-threw" | "capture-failed";
11
+ native: {
12
+ lengthUnit: number;
13
+ timestep: number;
14
+ solverIterations: number;
15
+ ccdSubsteps: number;
16
+ timings: {
17
+ stepMs: number;
18
+ collisionDetectionMs: number;
19
+ solverMs: number;
20
+ assemblyMs: number;
21
+ resolutionMs: number;
22
+ ccdMs: number;
23
+ };
24
+ convergence: ContactConvergenceStats;
25
+ } | null;
26
+ }
27
+ export interface PhysicsStepProfile {
28
+ sampleEvery: number;
29
+ sampleStartStep: number;
30
+ maxSamples: number;
31
+ attemptedSteps: number;
32
+ completedSteps: number;
33
+ failedSteps: number;
34
+ timedSteps: number;
35
+ /** Null if a finite sum could not be represented. */
36
+ totalWallTimeMs: number | null;
37
+ maxWallTimeMs: number | null;
38
+ slowestStep: number | null;
39
+ timingErrors: number;
40
+ captureErrors: number;
41
+ samplesOmittedForBudget: number;
42
+ /** Owned bounded samples. They do not estimate all unsampled native phases. */
43
+ samples: PhysicsStepSample[];
44
+ }
45
+ export interface PhysicsStepProfileOptions {
46
+ /** Capture every Nth managed call, default 32; integer 1..1,000,000. */
47
+ sampleEvery?: number;
48
+ /** First managed call eligible for capture, default 0; integer 0..1,000,000,000. */
49
+ sampleStartStep?: number;
50
+ /** Maximum retained/captured native profiles, default 32; integer 0..256. */
51
+ maxSamples?: number;
52
+ /** Monotonic milliseconds; defaults to performance.now. Failures are recorded. */
53
+ now?: () => number;
54
+ }
55
+ /** Borrow a world for explicitly managed steps. No listeners, render loop, timer,
56
+ * transport, or world ownership is created. Each sampled call restores the
57
+ * previous profiler setting, including on an exception. Unselected calls leave
58
+ * the setting alone. World.step exceptions propagate unchanged after accounting.
59
+ * Attach the actual engine/build identity when exporting a snapshot.
60
+ */
61
+ export declare function createPhysicsStepProfiler(world: World, options?: PhysicsStepProfileOptions): {
62
+ step(eventQueue?: EventQueue, hooks?: PhysicsHooks): void;
63
+ /** Deep-owned report; no live native query is performed here. */
64
+ snapshot(): PhysicsStepProfile;
65
+ };
@@ -10,6 +10,22 @@ import { PhysicsHooks } from "./physics_hooks";
10
10
  import { DebugRenderBuffers, DebugRenderPipeline } from "./debug_render_pipeline";
11
11
  import { KinematicCharacterController, PidAxesMask, PidController } from "../control";
12
12
  import { DynamicRayCastVehicleController } from "../control";
13
+ /** Last profiled step's restricted adaptive contact solves, including CCD passes.
14
+ * Counts describe solve groups/phases, not individual contacts or physical islands.
15
+ * Residuals are projected normal velocity errors in world units per second.
16
+ */
17
+ export interface ContactConvergenceStats {
18
+ compressionSolves: number;
19
+ compressionIterations: number;
20
+ compressionLimitHits: number;
21
+ /** Maximum terminal residual across eligible compression phases. */
22
+ maxCompressionResidual: number;
23
+ restitutionSolves: number;
24
+ restitutionIterations: number;
25
+ restitutionLimitHits: number;
26
+ /** Maximum terminal residual across eligible restitution phases. */
27
+ maxRestitutionResidual: number;
28
+ }
13
29
  /**
14
30
  * The physics world.
15
31
  *
@@ -568,6 +584,13 @@ export declare class World {
568
584
  * This count does not expose internal substep durations or time of impact.
569
585
  */
570
586
  ccdSubsteps(): number | null;
587
+ /** Owned observations from the last completed profiled step; null before
588
+ * that step, after toggling profiling, when disabled, or after restoration.
589
+ * Zero solves means no eligible adaptive path, not proof of convergence.
590
+ * A limit hit means the phase exhausted its budget above tolerance.
591
+ * Reading or modifying the returned object does not affect simulation.
592
+ */
593
+ contactConvergence(): ContactConvergenceStats | null;
571
594
  /**
572
595
  * The time spent in milliseconds by the last step to run the entire simulation step.
573
596
  *
@@ -895,6 +895,7 @@ export class RawPhysicsPipeline {
895
895
  free(): void;
896
896
  [Symbol.dispose](): void;
897
897
  ccd_substeps(): number | undefined;
898
+ contact_convergence(): Float64Array | undefined;
898
899
  is_profiler_enabled(): boolean;
899
900
  constructor();
900
901
  set_profiler_enabled(enabled: boolean): void;
@@ -2402,6 +2403,7 @@ export interface InitOutput {
2402
2403
  readonly rawnarrowphase_intersection_pairs_with: (a: number, b: number, c: number) => void;
2403
2404
  readonly rawnarrowphase_new: () => number;
2404
2405
  readonly rawphysicspipeline_ccd_substeps: (a: number) => number;
2406
+ readonly rawphysicspipeline_contact_convergence: (a: number, b: number) => void;
2405
2407
  readonly rawphysicspipeline_is_profiler_enabled: (a: number) => number;
2406
2408
  readonly rawphysicspipeline_new: () => number;
2407
2409
  readonly rawphysicspipeline_set_profiler_enabled: (a: number, b: number) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/rapier3d",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Rapier 3D with corrected contact witnesses, rotation precision and solver diagnostics",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",