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]);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
}
|