avocado-old/packages/physics/list.js
2019-03-22 11:25:20 -05:00

110 lines
2.6 KiB
JavaScript

import {Vector} from '@avocado/math';
import {Shape} from './shape';
import {shapeFromJSON} from './index';
export class ShapeList extends Shape {
constructor() {
super();
this._shapes = [];
this.on('shapesChanged', () => {
this._shapes.forEach((shape) => {
shape.off('aabbChanged');
shape.on('aabbChanged', () => {
this.emit('aabbChanged');
});
});
});
this.on('originChanged', (oldOrigin) => {
this._shapes.forEach((shape) => {
shape.emit('parentOriginChanged', oldOrigin, this.origin);
});
});
this.on('rotationChanged', (oldRotation) => {
this._shapes.forEach((shape) => {
shape.emit('parentRotationChanged', oldRotation, this.rotation);
});
});
this.on('scaleChanged', (oldScale) => {
this._shapes.forEach((shape) => {
shape.emit('parentScaleChanged', oldScale, this.scale);
});
});
}
*[Symbol.iterator]() {
for (const shape of this_shapes) {
yield shape;
}
}
get aabb() {
if (0 === this._shapes.length) {
return [0, 0, 0, 0];
}
const min = [Infinity, Infinity];
const max = [-Infinity, -Infinity];
for (const shape of this._shapes) {
const aabb = shape.aabb;
min[0] = aabb[0] < min[0] ? aabb[0] : min[0];
min[1] = aabb[1] < min[1] ? aabb[1] : min[1];
max[0] = aabb[0] > max[0] ? aabb[0] : max[0];
max[1] = aabb[1] > max[1] ? aabb[1] : max[1];
}
return Rectangle.translated(
[min[0], min[1], max[0] - min[0], max[1] - min[1]],
this.position
);
}
fromJSON(json) {
super.fromJSON(json);
if (json.shapes) {
const shapes = [];
json.shapes.forEach((shape) => {
shapes.push(shapeFromJSON(shape));
});
this._shapes = shapes;
this.emit('shapesChanged');
}
return this;
}
addShape(shape) {
this._shapes.push(shape);
this.emit('shapesChanged');
}
intersects(list) {
if (0 === this._shapes.length) {
return false;
}
if (!Rectangle.intersects(this.aabb, list.aabb)) {
return false;
}
// TODO: Quadtrees?
for (const shape of this._shapes) {
for (const otherShape of list._shapes) {
if (Rectangle.intersects(
Rectangle.translated(shape.aabb, this.position),
Rectangle.translated(otherShape.aabb, otherShape.position)
)) {
return true;
}
}
}
return false;
}
toJSON() {
return {
...super.toJSON(),
type: 'polygon',
shapes: this._shapes.map((shape) => {
return shape.toJSON();
}),
}
}
}