import { k as Space } from '../UserConstraint-VjSG2l0b.cjs'; import { S as SerializationOptions } from '../constraints-CenA8PgZ.cjs'; export { U as UserConstraintCodec } from '../constraints-CenA8PgZ.cjs'; import '../PhysicsMetrics-QzFDRdGh.cjs'; /** * Snapshot types for the nape-js serialization API (P37). * * All types are plain JSON-serializable objects — no class instances, no * circular references, no functions. */ /** Schema version — bumped on breaking snapshot format changes. */ declare const SNAPSHOT_VERSION = 1; interface Vec2Data { x: number; y: number; } interface MaterialData { elasticity: number; dynamicFriction: number; staticFriction: number; density: number; rollingFriction: number; } interface FluidPropertiesData { density: number; viscosity: number; gravity: Vec2Data | null; } interface InteractionFilterData { collisionGroup: number; collisionMask: number; sensorGroup: number; sensorMask: number; fluidGroup: number; fluidMask: number; } interface CircleShapeData { type: "circle"; radius: number; localCOM: Vec2Data; material: MaterialData; filter: InteractionFilterData; sensorEnabled: boolean; fluidEnabled: boolean; fluidProperties: FluidPropertiesData | null; } interface PolygonShapeData { type: "polygon"; localVerts: Vec2Data[]; material: MaterialData; filter: InteractionFilterData; sensorEnabled: boolean; fluidEnabled: boolean; fluidProperties: FluidPropertiesData | null; } interface CapsuleShapeData { type: "capsule"; width: number; height: number; localCOM: Vec2Data; material: MaterialData; filter: InteractionFilterData; sensorEnabled: boolean; fluidEnabled: boolean; fluidProperties: FluidPropertiesData | null; } type ShapeData = CircleShapeData | PolygonShapeData | CapsuleShapeData; type BodyTypeData = "DYNAMIC" | "STATIC" | "KINEMATIC"; type MassModeData = "DEFAULT" | "FIXED" | "FIXED_GROUP"; type InertiaModeData = "DEFAULT" | "FIXED" | "FIXED_GROUP"; type GravMassModeData = "DEFAULT" | "FIXED" | "SCALED"; interface BodyData { /** Stable numeric ID used to reference this body from constraints. */ id: number; type: BodyTypeData; position: Vec2Data; rotation: number; velocity: Vec2Data; angularVel: number; kinematicVel: Vec2Data; kinAngVel: number; surfaceVel: Vec2Data; force: Vec2Data; torque: number; massMode: MassModeData; /** Only present when massMode is "FIXED". */ mass: number | null; inertiaMode: InertiaModeData; /** Only present when inertiaMode is "FIXED". */ inertia: number | null; gravMassMode: GravMassModeData; gravMassScale: number; allowMovement: boolean; allowRotation: boolean; bullet: boolean; shapes: ShapeData[]; userData: Record | null; } /** Properties shared by every constraint type. */ interface ConstraintBaseData { /** * Index into SpaceSnapshot.bodies, `-2` for `space.world`, or null for no * body. */ body1Id: number | null; /** * Index into SpaceSnapshot.bodies, `-2` for `space.world`, or null for no * body. */ body2Id: number | null; active: boolean; ignore: boolean; stiff: boolean; frequency: number; damping: number; /** * `null` = unlimited (`Infinity`, the default). JSON has no Infinity — * `JSON.stringify` would turn it into `null` anyway, so the snapshot stores * `null` itself and stays identical across a stringify / parse round trip. */ maxForce: number | null; /** `null` = unlimited (`Infinity`, the default); see `maxForce`. */ maxError: number | null; breakUnderForce: boolean; breakUnderError: boolean; removeOnBreak: boolean; userData: Record | null; } interface PivotJointData extends ConstraintBaseData { type: "PivotJoint"; anchor1: Vec2Data; anchor2: Vec2Data; } interface DistanceJointData extends ConstraintBaseData { type: "DistanceJoint"; anchor1: Vec2Data; anchor2: Vec2Data; jointMin: number; jointMax: number; } interface AngleJointData extends ConstraintBaseData { type: "AngleJoint"; jointMin: number; jointMax: number; ratio: number; } interface MotorJointData extends ConstraintBaseData { type: "MotorJoint"; rate: number; ratio: number; } interface LineJointData extends ConstraintBaseData { type: "LineJoint"; anchor1: Vec2Data; anchor2: Vec2Data; direction: Vec2Data; jointMin: number; jointMax: number; } interface PulleyJointData extends ConstraintBaseData { type: "PulleyJoint"; /** Index into SpaceSnapshot.bodies, or null for a static world anchor. Absent in older snapshots. */ body3Id?: number | null; /** Index into SpaceSnapshot.bodies, or null for a static world anchor. Absent in older snapshots. */ body4Id?: number | null; anchor1: Vec2Data; anchor2: Vec2Data; anchor3: Vec2Data; anchor4: Vec2Data; jointMin: number; jointMax: number; ratio: number; } interface WeldJointData extends ConstraintBaseData { type: "WeldJoint"; anchor1: Vec2Data; anchor2: Vec2Data; phase: number; } interface SpringJointData extends ConstraintBaseData { type: "SpringJoint"; anchor1: Vec2Data; anchor2: Vec2Data; restLength: number; } /** * A `UserConstraint` saved through a {@link UserConstraintCodec}. * `body1Id` / `body2Id` mirror the first two entries of `bodyIds`. */ interface UserConstraintData extends ConstraintBaseData { type: "UserConstraint"; /** The codec's `type`. */ userType: string; /** Indices into SpaceSnapshot.bodies (null = no body), in the codec's `bodies()` order. */ bodyIds: (number | null)[]; /** The codec's `save()` output. */ data: Record; } type ConstraintData = PivotJointData | DistanceJointData | AngleJointData | MotorJointData | LineJointData | PulleyJointData | WeldJointData | SpringJointData | UserConstraintData; interface CompoundData { /** Body IDs belonging to this compound. */ bodyIds: number[]; /** Constraint indices (into SpaceSnapshot.constraints) belonging to this compound. */ constraintIndices: number[]; /** Child compound indices (into SpaceSnapshot.compounds). */ childIndices: number[]; } interface SpaceSnapshot { version: typeof SNAPSHOT_VERSION; gravity: Vec2Data; worldLinearDrag: number; worldAngularDrag: number; sortContacts: boolean; deterministic: boolean; broadphase: "SWEEP_AND_PRUNE" | "DYNAMIC_AABB_TREE" | "SPATIAL_HASH"; bodies: BodyData[]; constraints: ConstraintData[]; compounds: CompoundData[]; } /** * spaceToJSON — converts a live Space into a plain JSON-serializable SpaceSnapshot. * * UserConstraint instances are saved through the codecs passed in * `options.userConstraints` and skipped when no codec matches. * userData values are included only when JSON.stringify can round-trip them. */ /** * Serialize the complete state of a Space into a plain JSON-serializable object. * * - Bodies (position, velocity, shapes, mass, etc.) are fully captured. * - Built-in constraints are captured; a UserConstraint is captured when * `options.userConstraints` has a codec for its subclass, skipped otherwise. * - Compounds are captured as groupings of body IDs and constraint indices. * - Arbiters (collision contacts) are NOT captured — they are reconstructed * by the engine on the next simulation step. * - userData is included only for fields that survive a JSON round-trip. * * @param options - `userConstraints`: codecs for the UserConstraint subclasses * to save (see {@link UserConstraintCodec}). Pass the same codecs to `spaceFromJSON`. * * @example * ```ts * import { spaceToJSON, spaceFromJSON } from '@newkrok/nape-js/serialization'; * * const snapshot = spaceToJSON(space); * const json = JSON.stringify(snapshot); * // ... later: * const restored = spaceFromJSON(JSON.parse(json)); * ``` */ declare function spaceToJSON(space: Space, options?: SerializationOptions): SpaceSnapshot; /** * spaceFromJSON — reconstructs a Space from a SpaceSnapshot. * * All bodies are created fresh; constraints are wired up after bodies so that * body references are resolved correctly. */ /** * Reconstruct a Space from a SpaceSnapshot. * * The returned Space is fully configured: bodies, shapes, constraints, and * compounds are all added and ready for simulation. Call `space.step(dt)` to * start simulating. * * @param options - `userConstraints`: the codecs the snapshot was saved with. * @throws If the snapshot version is incompatible, or it holds a UserConstraint * whose codec is missing from `options.userConstraints`. * * @example * ```ts * import { spaceToJSON, spaceFromJSON } from '@newkrok/nape-js/serialization'; * * const snapshot = spaceToJSON(space); * const json = JSON.stringify(snapshot); * // ... send over network / save to disk ... * const restored = spaceFromJSON(JSON.parse(json)); * restored.step(1 / 60); * ``` */ declare function spaceFromJSON(snapshot: SpaceSnapshot, options?: SerializationOptions): Space; /** * spaceToBinary — converts a live Space into a compact Uint8Array snapshot. * * Designed for sub-millisecond rollback netcode. The binary format captures the * same physics state as spaceToJSON but skips userData (arbitrary JSON cannot be * efficiently binary-encoded; use spaceToJSON for userData). * * UserConstraint instances are saved through the codecs passed in * `options.userConstraints` (their state as a JSON string) and skipped when no * codec matches. * * Binary layout (little-endian): * Header: magic "NAPE" (4B), version u16, bodyCount u32, constraintCount u32, compoundCount u32 * Space: gravity (2×f64), worldLinearDrag f64, worldAngularDrag f64, sortContacts u8, deterministic u8, * broadphase u8 (0 sweep-and-prune, 1 AABB tree, 2 spatial hash) * Bodies: [per body — see writeBinaryBody] * Constraints: [per constraint — see writeBinaryConstraint]; body references are * i32 indices, -1 for no body, -2 for space.world * Compounds: [per compound — bodyCount u16, bodyIds u32[], constraintCount u16, constraintIdxs u32[], childCount u16, childIdxs u32[]] */ /** Binary format version — bumped on breaking layout changes. */ declare const BINARY_SNAPSHOT_VERSION = 2; /** * Serialize the complete physics state of a Space into a compact binary Uint8Array. * * This is the high-performance counterpart to `spaceToJSON`. It produces a much * smaller payload and is significantly faster to encode/decode — suitable for * per-frame rollback netcode, client-side prediction, and fast save/load. * * **Differences from spaceToJSON:** * - `userData` is NOT included (arbitrary JSON cannot be efficiently binary-encoded). * Use `spaceToJSON` if you need userData. * - UserConstraint instances are saved through `options.userConstraints` * codecs, same as JSON (their state is stored as a JSON string). * * @param options - `userConstraints`: codecs for the UserConstraint subclasses * to save (see {@link UserConstraintCodec}). Pass the same codecs to `spaceFromBinary`. * * @example * ```ts * import { spaceToBinary, spaceFromBinary } from '@newkrok/nape-js/serialization'; * * const snapshot = spaceToBinary(space); * // snapshot is a Uint8Array — send over network, save to IndexedDB, etc. * * const restored = spaceFromBinary(snapshot); * restored.step(1 / 60); * ``` */ declare function spaceToBinary(space: Space, options?: SerializationOptions): Uint8Array; /** * spaceFromBinary — reconstructs a Space from a binary Uint8Array snapshot. * * Counterpart to spaceToBinary. Reads the compact binary layout and rebuilds * all bodies, shapes, constraints, and compounds. * * Note: userData is NOT restored (it is not included in the binary format). */ /** * Reconstruct a Space from a binary Uint8Array snapshot. * * The returned Space is fully configured: bodies, shapes, constraints, and * compounds are all added and ready for simulation. Call `space.step(dt)` to * start simulating. * * **Note:** `userData` is NOT restored — binary snapshots do not include it. * Use `spaceFromJSON` if you need userData. * * @param options - `userConstraints`: the codecs the snapshot was saved with. * @throws If the magic bytes or version are invalid, or the snapshot holds a * UserConstraint whose codec is missing from `options.userConstraints`. * * @example * ```ts * import { spaceToBinary, spaceFromBinary } from '@newkrok/nape-js/serialization'; * * const snapshot = spaceToBinary(space); * const restored = spaceFromBinary(snapshot); * restored.step(1 / 60); * ``` */ declare function spaceFromBinary(data: Uint8Array, options?: SerializationOptions): Space; export { type AngleJointData, BINARY_SNAPSHOT_VERSION, type BodyData, type BodyTypeData, type CircleShapeData, type CompoundData, type ConstraintBaseData, type ConstraintData, type DistanceJointData, type FluidPropertiesData, type GravMassModeData, type InertiaModeData, type InteractionFilterData, type LineJointData, type MassModeData, type MaterialData, type MotorJointData, type PivotJointData, type PolygonShapeData, type PulleyJointData, SNAPSHOT_VERSION, SerializationOptions, type ShapeData, type SpaceSnapshot, type SpringJointData, type UserConstraintData, type Vec2Data, type WeldJointData, spaceFromBinary, spaceFromJSON, spaceToBinary, spaceToJSON };