UNPKG

@react-three/p2

Version:

2D physics based hooks for react-three-fiber

92 lines (82 loc) 2.63 kB
import { Body, Box, Capsule, Circle, Convex, Heightfield, Line, Material, Particle, Plane, vec2 } from 'p2-es' /** * @typedef { import('p2-es').MaterialOptions } MaterialOptions */ function createShape(type, args) { switch (type) { case 'Box': return new Box({ height: args[1], width: args[0] }) case 'Capsule': return new Capsule({ length: args[0], radius: args[1] }) case 'Circle': return new Circle({ radius: args[0] }) case 'Convex': return new Convex({ axes: args[1], vertices: args[0] }) case 'Particle': return new Particle() case 'Plane': return new Plane() case 'Line': return new Line({ length: args[0] }) case 'Heightfield': return new Heightfield({ elementWidth: args[1].elementWidth, heights: args[0] }) } } /** * @function * @param {Object} options * @param {string} options.uuid * @param {BodyProps} options.props * @param {BodyShapeType} options.type * @param {(materialOptions: MaterialOptions) => Material =} options.createMaterial * @returns {Body} */ const propsToBody = (options) => { const { uuid, props, type, createMaterial = (materialOptions) => new Material(materialOptions) } = options const { args = [], position = [0, 0], angle = 0, velocity = [0, 0], angularVelocity = 0, type: bodyType, isTrigger, mass, material, shapes, onCollide, collisionResponse, collisionGroup = -1, ...extra } = props const body = new Body({ ...extra, mass: bodyType === 'Static' ? 0 : mass, material: material ? createMaterial(material) : undefined, type: bodyType ? Body[bodyType.toUpperCase()] : undefined, }) body.uuid = uuid if (collisionResponse !== undefined) { body.collisionResponse = collisionResponse } if (type === 'Compound') { shapes.forEach(({ type, args, position, angle, material, ...extra }, i) => { body.addShape(createShape(type, args), position ? vec2.fromValues(...position) : undefined, angle) if (material) body.shapes[i].material = createMaterial(material) if (isTrigger) body.shapes[i].sensor = isTrigger Object.assign(body, extra) }) } else { const shape = createShape(type, args) shape.collisionGroup = collisionGroup if (material) shape.material = createMaterial(material) if (isTrigger) shape.sensor = isTrigger body.addShape(shape) } vec2.set(body.position, position[0], position[1]) body.angle = angle vec2.set(body.velocity, velocity[0], velocity[1]) body.angularVelocity = angularVelocity return body } export default propsToBody