avocado-old/packages/physics/matter/body.js

162 lines
3.5 KiB
JavaScript
Raw Normal View History

import {Composite, Bodies, Body as MatterBody, Vertices} from 'matter-js';
2019-03-24 03:24:35 -05:00
import {Vector} from '@avocado/math';
import {ShapeList, PolygonShape, RectangleShape} from '@avocado/physics';
import {AbstractBody} from '../abstract/body';
export class Body extends AbstractBody {
2019-04-08 15:20:28 -05:00
static collisionCategory(group) {
if (!('filterCategoryBit' in this)) {
this.filterCategoryBit = 0;
}
if (!('filterCategories' in this)) {
this.filterCategories = {};
}
if (!this.filterCategories[group]) {
this.filterCategories[group] = 1 << this.filterCategoryBit;
this.filterCategoryBit += 1;
}
return this.filterCategories[group];
}
2019-03-27 18:38:12 -05:00
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);
}
2019-03-24 03:24:35 -05:00
constructor(shape) {
super(shape);
[this.origin, this.matterBody] = this.constructor.bodyFromShape(shape);
2019-03-27 18:38:12 -05:00
this.constructor.associateBody(this.matterBody, this);
2019-03-24 03:24:35 -05:00
}
2019-03-24 18:58:26 -05:00
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,
];
}
2019-03-24 03:24:35 -05:00
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) {
const body = Bodies.rectangle(
0,
0,
2019-03-24 03:24:35 -05:00
shape.width,
shape.height,
);
return [shape.position, body];
2019-03-24 03:24:35 -05:00
}
else if (shape instanceof PolygonShape) {
const vectors = [];
for (const vertice of shape) {
vectors.push({
x: vertice[0],
y: vertice[1],
});
}
const centre = Vertices.centre(vectors);
const body = Bodies.fromVertices(
0,
0,
2019-03-24 03:24:35 -05:00
vectors,
);
const origin = Vector.add(
shape.position,
Vector.scale([centre.x, centre.y], 1),
);
return [origin, body];
2019-03-24 03:24:35 -05:00
}
}
get position() {
return [
this.matterBody.position.x,
this.matterBody.position.y,
];
}
set position(position) {
position = Vector.add(position, this.origin);
if (Vector.equalsClose(this.position, position)) {
return;
}
2019-03-24 03:24:35 -05:00
MatterBody.setPosition(this.matterBody, {
x: position[0],
y: position[1],
});
}
2019-04-08 15:20:28 -05:00
setCollision(category, mask, group = 0) {
MatterBody.set(this.matterBody, 'collisionFilter', {
category,
group,
mask,
});
}
setCollisionForEntity(entity) {
if (entity.is('collider')) {
const ctor = this.constructor;
const category = ctor.collisionCategory(entity.collisionGroup);
let mask = 0;
for (const group of entity.collidesWithGroups) {
mask = mask | ctor.collisionCategory(group);
}
this.setCollision(category, mask);
}
else {
this.setCollision(0, 0, -1);
}
}
2019-03-27 23:21:13 -05:00
get static() {
return this.matterBody.isStatic;
}
set static(isStatic) {
MatterBody.setStatic(this.matterBody, isStatic);
}
2019-04-12 20:25:40 -05:00
get vertices() {
const vertices = [];
for (const {x, y} of this.matterBody.vertices) {
vertices.push([x, y]);
}
return vertices;
}
2019-03-24 03:24:35 -05:00
}