import type { ContactMaterialOptions, MaterialOptions, RayOptions as RayOptionsImpl, Shape } from 'p2-es';
import type { MutableRefObject } from 'react';
import type { Object3D } from 'three';
import type { CannonWorkerAPI } from 'cannon-worker-api';
import type { AtomicProps, BodyProps, BodyShapeType } from './hooks';
export declare type Duplet = [number, number];
export declare type Broadphase = 'Naive' | 'SAP';
export declare type Solver = 'GS' | 'Split';
export declare type Buffers = {
    positions: Float32Array;
    quaternions: Float32Array;
};
export declare type Refs = {
    [uuid: string]: Object3D;
};
export declare type ConstraintTypes = 'Distance' | 'Gear' | 'Lock' | 'Prismatic' | 'Revolute';
export interface ConstraintOptns {
    collideConnected?: boolean;
}
export interface DistanceConstraintOpts extends ConstraintOptns {
    distance?: number;
    localAnchorA?: Duplet;
    localAnchorB?: Duplet;
    maxForce?: number;
}
export interface GearConstraintOpts extends ConstraintOptns {
    angle?: number;
    maxTorque?: number;
    ratio?: number;
}
export interface LockConstraintOpts extends ConstraintOptns {
    localAngleB?: number;
    localOffsetB?: Duplet;
    maxForce?: number;
}
export interface PrismaticConstraintOpts extends ConstraintOptns {
    disableRotationalLock?: boolean;
    localAnchorA?: Duplet;
    localAnchorB?: Duplet;
    localAxisA?: Duplet;
    lowerLimit?: number;
    maxForce?: number;
    upperLimit?: number;
}
export interface RevoluteConstraintOpts extends ConstraintOptns {
    localPivotA?: Duplet;
    localPivotB?: Duplet;
    maxForce?: number;
    worldPivot?: Duplet;
}
export interface SpringOptns {
    damping?: number;
    localAnchorA?: Duplet;
    localAnchorB?: Duplet;
    restLength?: number;
    stiffness?: number;
    worldAnchorA?: Duplet;
    worldAnchorB?: Duplet;
}
export interface WheelInfoOptions {
    localPosition?: Duplet;
    sideFriction?: number;
}
declare type WorkerContact = WorkerCollideEvent['data']['contact'];
export declare type CollideEvent = Omit<WorkerCollideEvent['data'], 'body' | 'target' | 'contact'> & {
    body: Object3D;
    contact: Omit<WorkerContact, 'bi' | 'bj'> & {
        bi: Object3D;
        bj: Object3D;
    };
    target: Object3D;
};
export declare type CollideBeginEvent = {
    body: Object3D;
    op: 'event';
    target: Object3D;
    type: 'collideBegin';
};
export declare type CollideEndEvent = {
    body: Object3D;
    op: 'event';
    target: Object3D;
    type: 'collideEnd';
};
export declare type RayhitEvent = Omit<WorkerRayhitEvent['data'], 'body'> & {
    body: Object3D | null;
};
declare type CannonEvent = CollideBeginEvent | CollideEndEvent | CollideEvent | RayhitEvent;
declare type CallbackByType<T extends {
    type: string;
}> = {
    [K in T['type']]?: T extends {
        type: K;
    } ? (e: T) => void : never;
};
declare type CannonEvents = {
    [uuid: string]: Partial<CallbackByType<CannonEvent>>;
};
export declare type Subscription = Partial<{
    [K in SubscriptionName]: (value: PropValue<K>) => void;
}>;
export declare type Subscriptions = Partial<{
    [id: number]: Subscription;
}>;
export declare type PropValue<T extends SubscriptionName = SubscriptionName> = T extends AtomicName ? AtomicProps[T] : T extends VectorName ? Duplet : never;
export declare const atomicNames: readonly ["allowSleep", "angle", "angularDamping", "angularVelocity", "collisionFilterGroup", "collisionFilterMask", "collisionResponse", "fixedRotation", "isTrigger", "linearDamping", "mass", "material", "sleepSpeedLimit", "sleepTimeLimit", "userData"];
export declare type AtomicName = typeof atomicNames[number];
export declare const vectorNames: readonly ["position", "velocity"];
export declare type VectorName = typeof vectorNames[number];
export declare const subscriptionNames: readonly ["allowSleep", "angle", "angularDamping", "angularVelocity", "collisionFilterGroup", "collisionFilterMask", "collisionResponse", "fixedRotation", "isTrigger", "linearDamping", "mass", "material", "sleepSpeedLimit", "sleepTimeLimit", "userData", "position", "velocity", "collisions", "raysData"];
export declare type SubscriptionName = typeof subscriptionNames[number];
export declare type SetOpName<T extends AtomicName | VectorName | WorldPropName> = `set${Capitalize<T>}`;
declare type Operation<T extends OpName, P> = {
    op: T;
} & (P extends symbol ? {} : {
    props: P;
});
declare type WithUUID<T extends OpName, P = symbol> = Operation<T, P> & {
    uuid: string;
};
declare type WithUUIDs<T extends OpName, P = symbol> = Operation<T, P> & {
    uuid: string[];
};
declare type AddConstraintProps = [
    uuidA: string,
    uuidB: string,
    options: {
        angle?: number;
        collideConnected?: boolean;
        disableRotationalLock?: boolean;
        distance?: number;
        localAnchorA?: Duplet;
        localAnchorB?: Duplet;
        localAngleB?: number;
        localAxisA?: Duplet;
        localOffsetB?: Duplet;
        localPivotA?: Duplet;
        localPivotB?: Duplet;
        lowerLimit?: number;
        maxForce?: number;
        maxTorque?: number;
        ratio?: number;
        upperLimit?: number;
        worldPivot?: Duplet;
    }
];
declare type AddContactMaterialProps = [
    materialA: MaterialOptions,
    materialB: MaterialOptions,
    options: ContactMaterialOptions
];
export declare type RayMode = 'Closest' | 'Any' | 'All';
declare type AddRayProps = {
    from: Duplet;
    mode: RayMode;
    to: Duplet;
} & Pick<RayOptionsImpl, 'checkCollisionResponse' | 'collisionGroup' | 'collisionMask' | 'skipBackfaces'>;
export declare type RayOptions = Omit<AddRayProps, 'mode'>;
declare type AtomicMessage<T extends AtomicName> = WithUUID<SetOpName<T>, AtomicProps[T]>;
declare type VectorMessage = WithUUID<SetOpName<VectorName>, Duplet>;
declare type SerializableBodyProps = {
    onCollide: boolean;
};
export declare type SubscriptionTarget = 'bodies' | 'vehicles' | 'controllers';
declare type SubscribeMessageProps = {
    id: number;
    target: SubscriptionTarget;
    type: SubscriptionName;
};
export declare type Observation = {
    [K in AtomicName]: [id: number, value: PropValue<K>, type: K];
}[AtomicName];
export declare type WorkerFrameMessage = {
    data: Buffers & {
        active: boolean;
        bodies?: string[];
        observations: Observation[];
        op: 'frame';
    };
};
export declare type WorkerCollideEvent = {
    data: {
        body: string;
        collisionFilters: {
            bodyFilterGroup: number;
            bodyFilterMask: number;
            targetFilterGroup: number;
            targetFilterMask: number;
        };
        contact: {
            bi: string;
            bj: string;
            contactNormal: number[];
            contactPoint: number[];
            id: number;
            impactVelocity: number;
            ni: number[];
            ri: number[];
            rj: number[];
        };
        op: 'event';
        target: string;
        type: 'collide';
    };
};
export declare type WorkerRayhitEvent = {
    data: {
        body: string | null;
        distance: number;
        hasHit: boolean;
        hitFaceIndex: number;
        hitNormalWorld: number[];
        hitPointWorld: number[];
        op: 'event';
        ray: {
            collisionFilterGroup: number;
            collisionFilterMask: number;
            direction: number[];
            from: number[];
            to: number[];
            uuid: string;
        };
        rayFromWorld: number[];
        rayToWorld: number[];
        shape: (Omit<Shape, 'body'> & {
            body: string;
        }) | null;
        shouldStop: boolean;
        type: 'rayhit';
    };
};
export declare type WorkerCollideBeginEvent = {
    data: {
        bodyA: string;
        bodyB: string;
        op: 'event';
        type: 'collideBegin';
    };
};
export declare type WorkerCollideEndEvent = {
    data: {
        bodyA: string;
        bodyB: string;
        op: 'event';
        type: 'collideEnd';
    };
};
export declare type WorkerEventMessage = WorkerCollideBeginEvent | WorkerCollideEndEvent | WorkerCollideEvent | WorkerRayhitEvent;
export declare type IncomingWorkerMessage = WorkerEventMessage | WorkerFrameMessage;
export declare type WorldPropName = 'axisIndex' | 'broadphase' | 'gravity' | 'iterations' | 'tolerance';
export declare type StepProps = {
    maxSubSteps?: number;
    stepSize: number;
    timeSinceLastCalled?: number;
};
export declare type WorldProps = {
    allowSleep: boolean;
    axisIndex: 0 | 1 | 2;
    broadphase: Broadphase;
    defaultContactMaterial: ContactMaterialOptions;
    gravity: Duplet;
    iterations: number;
    normalIndex: 0 | 1 | 2;
    quatNormalizeFast: boolean;
    quatNormalizeSkip: number;
    solver: Solver;
    tolerance: number;
};
declare type WorldMessage<T extends WorldPropName> = Operation<SetOpName<T>, WorldProps[T]>;
export declare type CannonMessageMap = {
    addBodies: WithUUIDs<'addBodies', SerializableBodyProps[]> & {
        type: BodyShapeType;
    };
    addConstraint: WithUUID<'addConstraint', AddConstraintProps> & {
        type: 'Prismatic' | 'Revolute' | ConstraintTypes;
    };
    addContactMaterial: WithUUID<'addContactMaterial', AddContactMaterialProps>;
    addKinematicCharacterController: WithUUID<'addKinematicCharacterController', [
        bodyUUID: string,
        collisionMask: number,
        accelerationTimeAirborne?: number,
        accelerationTimeGrounded?: number,
        moveSpeed?: number,
        wallSlideSpeedMax?: number,
        wallStickTime?: number,
        wallJumpClimb?: Duplet,
        wallJumpOff?: Duplet,
        wallLeap?: Duplet,
        timeToJumpApex?: number,
        maxJumpHeight?: number,
        minJumpHeight?: number,
        velocityXSmoothing?: number,
        velocityXMin?: number,
        maxClimbAngle?: number,
        maxDescendAngle?: number,
        skinWidth?: number,
        dstBetweenRays?: number
    ]>;
    addPlatformController: WithUUID<'addPlatformController', [
        bodyUUID: string,
        passengerMask: number,
        localWaypoints: Duplet[],
        speed?: number,
        skinWidth?: number,
        dstBetweenRays?: number
    ]>;
    addRay: WithUUID<'addRay', AddRayProps>;
    addSpring: WithUUID<'addSpring', [uuidA: string, uuidB: string, options: SpringOptns]>;
    addTopDownVehicle: WithUUID<'addTopDownVehicle', [chassisBodyUUID: string, wheelInfos: WheelInfoOptions[]]>;
    applyForce: WithUUID<'applyForce', [force: Duplet, worldPoint: Duplet]>;
    applyImpulse: WithUUID<'applyImpulse', [impulse: Duplet, worldPoint: Duplet]>;
    applyLocalForce: WithUUID<'applyLocalForce', [force: Duplet, localPoint: Duplet]>;
    applyLocalImpulse: WithUUID<'applyLocalImpulse', [impulse: Duplet, localPoint: Duplet]>;
    applyTopDownVehicleEngineForce: WithUUID<'applyTopDownVehicleEngineForce', [
        value: number,
        wheelIndex: number
    ]>;
    applyTorque: WithUUID<'applyTorque', [torque: Duplet]>;
    disableConstraintMotor: WithUUID<'disableConstraintMotor'>;
    enableConstraintMotor: WithUUID<'enableConstraintMotor'>;
    init: Operation<'init', WorldProps>;
    removeBodies: WithUUIDs<'removeBodies'>;
    removeConstraint: WithUUID<'removeConstraint'>;
    removeContactMaterial: WithUUID<'removeContactMaterial'>;
    removeKinematicCharacterController: WithUUID<'removeKinematicCharacterController'>;
    removePlatformController: WithUUID<'removePlatformController'>;
    removeRay: WithUUID<'removeRay'>;
    removeSpring: WithUUID<'removeSpring'>;
    removeTopDownVehicle: WithUUID<'removeTopDownVehicle'>;
    setAllowSleep: AtomicMessage<'allowSleep'>;
    setAngle: WithUUID<SetOpName<'angle'>, number>;
    setAngularDamping: AtomicMessage<'angularDamping'>;
    setAngularVelocity: AtomicMessage<'angularVelocity'>;
    setAxisIndex: WorldMessage<'axisIndex'>;
    setBroadphase: WorldMessage<'broadphase'>;
    setCollisionFilterGroup: AtomicMessage<'collisionFilterGroup'>;
    setCollisionFilterMask: AtomicMessage<'collisionFilterMask'>;
    setCollisionResponse: AtomicMessage<'collisionResponse'>;
    setConstraintMotorSpeed: WithUUID<'setConstraintMotorSpeed', number>;
    setFixedRotation: AtomicMessage<'fixedRotation'>;
    setGravity: WorldMessage<'gravity'>;
    setIsTrigger: AtomicMessage<'isTrigger'>;
    setIterations: WorldMessage<'iterations'>;
    setKinematicCharacterControllerInput: WithUUID<'setKinematicCharacterControllerInput', Duplet>;
    setKinematicCharacterControllerJump: WithUUID<'setKinematicCharacterControllerJump', boolean>;
    setLinearDamping: AtomicMessage<'linearDamping'>;
    setMass: AtomicMessage<'mass'>;
    setMaterial: AtomicMessage<'material'>;
    setPosition: VectorMessage;
    setSleepSpeedLimit: AtomicMessage<'sleepSpeedLimit'>;
    setSleepTimeLimit: AtomicMessage<'sleepTimeLimit'>;
    setSpringDamping: WithUUID<'setSpringDamping', number>;
    setSpringRestLength: WithUUID<'setSpringRestLength', number>;
    setSpringStiffness: WithUUID<'setSpringStiffness', number>;
    setTolerance: WorldMessage<'tolerance'>;
    setTopDownVehicleBrake: WithUUID<'setTopDownVehicleBrake', [brake: number, wheelIndex: number]>;
    setTopDownVehicleSteeringValue: WithUUID<'setTopDownVehicleSteeringValue', [
        value: number,
        wheelIndex: number
    ]>;
    setUserData: AtomicMessage<'userData'>;
    setVelocity: VectorMessage;
    sleep: WithUUID<'sleep'>;
    step: Operation<'step', StepProps> & {
        positions: Float32Array;
        quaternions: Float32Array;
    };
    subscribe: WithUUID<'subscribe', SubscribeMessageProps>;
    unsubscribe: Operation<'unsubscribe', number>;
    wakeUp: WithUUID<'wakeUp'>;
};
declare type OpName = keyof CannonMessageMap;
export declare type CannonMessageBody<T extends OpName> = Omit<CannonMessageMap[T], 'op'>;
export declare type CannonMessageProps<T extends OpName> = CannonMessageMap[T] extends {
    props: unknown;
} ? CannonMessageMap[T]['props'] : never;
export declare type CannonMessage = CannonMessageMap[OpName];
export interface CannonWebWorker extends Worker {
    onmessage: (e: IncomingWorkerMessage) => void;
    postMessage(message: CannonMessage, transfer: Transferable[]): void;
    postMessage(message: CannonMessage, options?: StructuredSerializeOptions): void;
    terminate: () => void;
}
export declare type ProviderContext = {
    bodies: MutableRefObject<{
        [uuid: string]: number;
    }>;
    events: CannonEvents;
    refs: Refs;
    subscriptions: Subscriptions;
    worker: CannonWorkerAPI;
};
export declare type DebugApi = {
    add(id: string, props: BodyProps, type: BodyShapeType): void;
    remove(id: string): void;
};
export declare const context: import("react").Context<ProviderContext>;
export declare const debugContext: import("react").Context<DebugApi>;
export {};
