assassin-bug/framework/physics/world.js

55 lines
1.8 KiB
JavaScript
Raw Normal View History

2022-11-26 01:22:02 +00:00
import { Octree } from './octree';
import { EventBus } from '../event-bus';
import { Vec3 } from './vec3';
import { AABB } from './aabb';
export class World extends EventBus {
constructor(dimensions, octreeOptions) {
super();
if (!octreeOptions) {
this.octreeOptions = {
position: new Vec3({ x: 0, y: 0, z: 0 }),
dimensions: new Vec3(this.dimensions),
maxLevels: 50,
maxObjects: 50
};
}
else {
this.octreeOptions = octreeOptions;
}
this.dimensions = dimensions;
this.objects = [];
}
setGravity(grav) {
this.gravity = grav;
}
addObject(obj) {
this.objects.push(obj);
}
removeObject(obj) {
this.objects = this.objects.filter((val) => val !== obj);
}
step(dt) {
const octree = new Octree(this.octreeOptions.dimensions, this.octreeOptions.maxObjects, this.octreeOptions.maxLevels);
this.objects.forEach((obj) => octree.insert(obj));
this.objects.forEach((obj) => {
let velocity = obj.velocity.clone();
velocity.multiply(new Vec3({ x: dt, y: dt, z: dt }));
let gravity = this.gravity.clone();
gravity.multiply(new Vec3({ x: dt, y: dt, z: dt }));
obj.position.add(velocity);
if (obj.affectedByGravity) {
obj.velocity.add(gravity);
}
this.checkCollisions(obj, octree);
});
}
checkCollisions(obj, octree) {
const potentialCandidates = octree.find(obj.position, obj.dimensions);
potentialCandidates.forEach((candidate) => {
if (AABB(obj, candidate)) {
this.emit('collision', [obj, candidate]);
}
});
}
}