UNPKG

@react-three/p2

Version:

2D physics based hooks for react-three-fiber

400 lines (399 loc) 14.9 kB
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 {};