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