55 lines
1.8 KiB
JavaScript
55 lines
1.8 KiB
JavaScript
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]);
|
|
}
|
|
});
|
|
}
|
|
}
|