import {Composite, Bodies, Body as MatterBody} from 'matter-js'; import {Vector} from '@avocado/math'; import {ShapeList, PolygonShape, RectangleShape} from '@avocado/physics'; import {AbstractBody} from '../abstract/body'; import { Rectangle } from '../../math'; export class Body extends AbstractBody { static lookupBody(matterBody) { if (this.bodies) { return this.bodies.get(matterBody); } } static associateBody(matterBody, avocadoBody) { if (!this.bodies) { this.bodies = new Map(); } this.bodies.set(matterBody, avocadoBody); } constructor(shape) { super(shape); this.matterBody = this.constructor.bodyFromShape(shape); this.constructor.associateBody(this.matterBody, this); } get aabb() { const bounds = this.matterBody.bounds; return [ bounds.min.x, bounds.min.y, bounds.max.x - bounds.min.x, bounds.max.y - bounds.min.y, ]; } applyForce(force) { MatterBody.applyForce( this.matterBody, this.matterBody.position, { x: force[0], y: force[1], } ); } applyImpulse(impulse, elapsed) { impulse = Vector.scale(impulse, elapsed); MatterBody.translate(this.matterBody, { x: impulse[0], y: impulse[1], }); } static bodyFromShape(shape) { if (shape instanceof RectangleShape) { return Bodies.rectangle( shape.x, shape.y, shape.width, shape.height, ); } else if (shape instanceof PolygonShape) { const vectors = []; for (const vertice of shape) { vectors.push({ x: vertice[0], y: vertice[1], }); } return Bodies.fromVertices( shape.x, shape.y, vectors, ); } } get position() { return [ this.matterBody.position.x, this.matterBody.position.y, ]; } set position(position) { if (Vector.equalsClose(this.position, position)) { return; } MatterBody.setPosition(this.matterBody, { x: position[0], y: position[1], }); } get static() { return this.matterBody.isStatic; } set static(isStatic) { MatterBody.setStatic(this.matterBody, isStatic); } }