Documentation
    Preparing search index...

    Interface SolverJointAccess

    What PhysicsWorld needs from a solver joint by joint (§28, §33, §37; plan P6-1, P6-2).

    See the module header for why this is separate from PhysicsSolverAdapter and from SolverBodyAccess. Everything SolverBodyAccess owes — handles are the adapter's own, reads take out parameters, ids are monotonic and never reused, no user callbacks, no clock — applies here unchanged.

    SolverJointAccess.getJointReaction reports the impulse the constraint applied during the last step, in newton-seconds and newton-metre-seconds, because that is what a constraint solver actually accumulates — a force would be a number the adapter had to invent a delta for. PhysicsWorld divides by its own fixed delta to get the newtons and newton-metres §28's break thresholds are stated in, which keeps the conversion in one place and makes it visible.

    An adapter whose solver cannot report reactions declares SolverJointAccess.reportsJointReactions false and is never asked; the world then refuses a joint carrying a break threshold rather than accepting one it can never enforce (plan P6-2: "if unavailable, breakage is staged with a dated note, not faked"). Rapier 0.19.3's JavaScript bindings expose no joint reaction (verified against the installed typings, WP-6.1); WP-6.2/6.3 confirm that against the wasm and report honestly.

    interface SolverJointAccess {
        reportsJointReactions: boolean;
        forEachJoint(visit: (handle: PhysicsJointHandle, id: number) => void): void;
        getJointId(handle: PhysicsJointHandle): number;
        getJointReaction(
            handle: PhysicsJointHandle,
            outLinear: Vector3,
            outAngular: Vector3,
        ): void;
        setJointAnchors(
            handle: PhysicsJointHandle,
            anchorA: Vector3,
            anchorB: Vector3,
        ): void;
        setJointCollisionEnabled(
            handle: PhysicsJointHandle,
            enabled: boolean,
        ): void;
        setJointLimits(handle: PhysicsJointHandle, min: number, max: number): void;
        setJointMotor(handle: PhysicsJointHandle, motor: SolverJointMotor): void;
    }
    Index
    reportsJointReactions: boolean

    Whether SolverJointAccess.getJointReaction reports anything real.

    Declared, not discovered: a world checks it when a breakable joint is registered, so an adapter that cannot report reactions fails the registration loudly instead of silently never breaking a joint.

    • Replaces both body-local anchors after creation (§28, PH-22f).

      anchorA is in bodyA's local frame and anchorB in bodyB's — the same space createJoint received after PhysicsWorld.addJoint converted the world-space constructor options. The caller supplies local-space points; this method must not re-measure against any pose.

      Rapier implements this as ImpulseJoint.setAnchor1 / setAnchor2, which exist on the base joint class in both dimensions, so every shipped §28 type can be re-anchored. Same call discipline as SolverJointAccess.setJointLimits: at most once per joint per fixed step, from the scene→solver phase, only for a joint that queued the change.

      Parameters

      Returns void

    • Turns contact generation between the two joined bodies on or off after creation (§28 collisionEnabled; PH-22f, 2026-08-08).

      The third of §28's live reconfigurations: Rapier's base ImpulseJoint carries setContactsEnabled for every joint type in both dimensions. Axis, rope length, spring terms and the spherical swing cone stay frozen (see joints.ts's table). Anchors are the fourth live write — see SolverJointAccess.setJointAnchors.

      Same call discipline as SolverJointAccess.setJointLimits: at most once per joint per fixed step, from the scene→solver phase, only for a joint that queued the change.

      Parameters

      Returns void

    • Reconfigures a joint's travel limits after creation (§28 "limits").

      Radians for a revolute joint, metres for a prismatic one, with min <= max already validated by the engine. Called at most once per joint per fixed step, from the scene→solver phase, and only for a joint whose class actually queued a change — a joint nobody touches costs nothing.

      An adapter whose solver cannot re-limit the joint type in question must throw a FourError naming the type rather than ignoring the command: a limit that silently does not move is a wrong simulation.

      Parameters

      Returns void