decla-red/frontend/src/scripts/physics/physics.ts
2020-10-05 19:07:17 +02:00

121 lines
3.6 KiB
TypeScript

/*import { vec2 } from 'gl-matrix';
import { rotate90Deg } from '../helper/rotate-90-deg';
import { settings } from '../settings';
import { BoundingBoxBase } from './bounds/bounding-box-base';
import { BoundingCircle } from './bounds/bounding-circle';
import { ImmutableBoundingBox } from './bounds/immutable-bounding-box';
import { BoundingBoxList } from './containers/bounding-box-list';
import { BoundingBoxTree } from './containers/bounding-box-tree';
export class Physics {
private isTreeInitialized = false;
private staticBoundingBoxesWaitList = [];
private staticBoundingBoxes = new BoundingBoxTree();
private dynamicBoundingBoxes = new BoundingBoxList();
public addStaticBoundingBox(boundingBox: ImmutableBoundingBox) {
if (!this.isTreeInitialized) {
this.staticBoundingBoxesWaitList.push(boundingBox);
} else {
this.staticBoundingBoxes.insert(boundingBox);
}
}
public addDynamicBoundingBox(boundingBox: BoundingBoxBase) {
this.dynamicBoundingBoxes.insert(boundingBox);
}
public removeDynamicBoundingBox(boundingBox: BoundingBoxBase) {
this.dynamicBoundingBoxes.remove(boundingBox);
}
public tryMovingDynamicCircle(
circle: BoundingCircle,
delta: vec2
): {
realDelta: vec2;
hitSurface: boolean;
normal?: vec2;
tangent?: vec2;
} {
circle.center = vec2.add(circle.center, circle.center, delta);
const intersecting = this.findIntersecting(circle.boundingBox).filter(
(b) =>
b.owner !== circle.owner && circle.areIntersecting(b.owner) && b.owner.canCollide
);
if (intersecting.length === 0) {
return {
realDelta: delta,
hitSurface: false,
};
}
const points = circle.getPerimeterPoints(settings.hitDetectionCirclePointCount);
const distancesOfPoints = points
.map((point) => ({
point,
closest: intersecting
.map((i) => ({
inverted: i.isInverted,
distance: i.owner.distance(point),
}))
.sort((a, b) => a.distance - b.distance)[0],
}))
.filter((i) => i.closest);
const distancesOfIntersectingPoints = distancesOfPoints.filter(
(d) =>
(d.closest.distance > 0 && d.closest.inverted) ||
(d.closest.distance < 0 && !d.closest.inverted)
);
if (distancesOfIntersectingPoints.length === 0) {
return {
realDelta: delta,
hitSurface: false,
};
}
const deltas = distancesOfIntersectingPoints.map((pointDistance) => {
vec2.subtract(pointDistance.point, circle.center, pointDistance.point);
vec2.normalize(pointDistance.point, pointDistance.point);
vec2.scale(
pointDistance.point,
pointDistance.point,
(pointDistance.closest.inverted ? 1 : -1) * pointDistance.closest.distance
);
return pointDistance.point;
});
const approxNormal = deltas.reduce(
(sum, current) => vec2.add(sum, sum, current),
vec2.create()
);
vec2.scale(approxNormal, approxNormal, 1 / deltas.length);
circle.center = vec2.add(circle.center, circle.center, approxNormal);
return {
realDelta: delta,
hitSurface: true,
normal: vec2.normalize(approxNormal, approxNormal),
tangent: rotate90Deg(approxNormal),
};
}
public findIntersecting(box: BoundingBoxBase): Array<BoundingBoxBase> {
return [
...this.staticBoundingBoxes.findIntersecting(box),
...this.dynamicBoundingBoxes.findIntersecting(box),
];
}
public start() {
this.staticBoundingBoxes.build(this.staticBoundingBoxesWaitList);
this.isTreeInitialized = true;
}
}
*/