diff options
author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2023-08-12 13:49:16 -0600 |
---|---|---|
committer | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2023-08-12 13:49:16 -0600 |
commit | c6e9baa0009f7cce0f6ff156a3957ef04a8cb684 (patch) | |
tree | 9766a4a33ad1c86aa71a5f92daf8917f3e5f5eed /engine/structures | |
parent | b67ffb57c1bf6e9628339a3f43c71ccebdb46136 (diff) | |
download | jumpstorm-c6e9baa0009f7cce0f6ff156a3957ef04a8cb684.tar.gz jumpstorm-c6e9baa0009f7cce0f6ff156a3957ef04a8cb684.zip |
the great engine refactor
Diffstat (limited to 'engine/structures')
-rw-r--r-- | engine/structures/QuadTree.ts | 91 |
1 files changed, 57 insertions, 34 deletions
diff --git a/engine/structures/QuadTree.ts b/engine/structures/QuadTree.ts index 7913e59..d1ff3b1 100644 --- a/engine/structures/QuadTree.ts +++ b/engine/structures/QuadTree.ts @@ -1,6 +1,4 @@ import type { Coord2D, Dimension2D } from "../interfaces"; -import { ComponentNames, BoundingBox } from "../components"; -import { Entity } from "../entities"; interface BoxedEntry { id: number; @@ -30,21 +28,26 @@ export class QuadTree { dimension: Dimension2D, maxLevels: number, splitThreshold: number, - level?: number + level?: number, ) { - this.children = []; + this.children = new Map<Quadrant, QuadTree>(); this.objects = []; this.maxLevels = maxLevels; this.splitThreshold = splitThreshold; this.level = level ?? 0; + + this.topLeft = topLeft; + this.dimension = dimension; } public insert(id: number, dimension: Dimension2D, center: Coord2D): void { + const box: BoxedEntry = { id, center, dimension }; if (this.hasChildren()) { - this.getIndices(boundingBox).forEach((i) => - this.children[i].insert(id, dimension, center) - ); + this.getQuadrants(box).forEach((quadrant) => { + const quadrantBox = this.children.get(quadrant); + quadrantBox?.insert(id, dimension, center); + }); return; } @@ -74,9 +77,10 @@ export class QuadTree { if (this.hasChildren()) { this.getQuadrants(boxedEntry).forEach((quadrant) => { - this.children - .get(quadrant) - .getNeighborIds(boxedEntry) + const quadrantBox = this.children.get(quadrant); + + quadrantBox + ?.getNeighborIds(boxedEntry) .forEach((id) => neighbors.push(id)); }); } @@ -88,15 +92,17 @@ export class QuadTree { const halfWidth = this.dimension.width / 2; const halfHeight = this.dimension.height / 2; - [ - [Quadrant.I, { x: this.topLeft.x + halfWidth, y: this.topLeft.y }], - [Quadrant.II, { ...this.topLeft }], - [Quadrant.III, { x: this.topLeft.x, y: this.topLeft.y + halfHeight }], + ( [ - Quadrant.IV, - { x: this.topLeft.x + halfWidth, y: this.topLeft.y + halfHeight }, - ], - ].forEach(([quadrant, pos]) => { + [Quadrant.I, { x: this.topLeft.x + halfWidth, y: this.topLeft.y }], + [Quadrant.II, { ...this.topLeft }], + [Quadrant.III, { x: this.topLeft.x, y: this.topLeft.y + halfHeight }], + [ + Quadrant.IV, + { x: this.topLeft.x + halfWidth, y: this.topLeft.y + halfHeight }, + ], + ] as [[Quadrant, Coord2D]] + ).forEach(([quadrant, pos]) => { this.children.set( quadrant, new QuadTree( @@ -104,34 +110,48 @@ export class QuadTree { { width: halfWidth, height: halfHeight }, this.maxLevels, this.splitThreshold, - this.level + 1 - ) + this.level + 1, + ), ); }); } - private getQuandrants(boxedEntry: BoxedEntry): Quadrant[] { + private getQuadrants(boxedEntry: BoxedEntry): Quadrant[] { const treeCenter: Coord2D = { x: this.topLeft.x + this.dimension.width / 2, y: this.topLeft.y + this.dimension.height / 2, }; - return [ - [Quadrant.I, (x, y) => x >= treeCenter.x && y < treeCenter.y], - [Quadrant.II, (x, y) => x < treeCenter.x && y < treeCenter.y], - [Quadrant.III, (x, y) => x < treeCenter.x && y >= treeCenter.y], - [Quadrant.IV, (x, y) => x >= treeCenter.x && y >= treeCenter.y], - ] + return ( + [ + [ + Quadrant.I, + (x: number, y: number) => x >= treeCenter.x && y < treeCenter.y, + ], + [ + Quadrant.II, + (x: number, y: number) => x < treeCenter.x && y < treeCenter.y, + ], + [ + Quadrant.III, + (x: number, y: number) => x < treeCenter.x && y >= treeCenter.y, + ], + [ + Quadrant.IV, + (x: number, y: number) => x >= treeCenter.x && y >= treeCenter.y, + ], + ] as [[Quadrant, (x: number, y: number) => boolean]] + ) .filter( ([_quadrant, condition]) => condition( boxedEntry.center.x + boxedEntry.dimension.width / 2, - boxedEntry.center.y + boxedEntry.dimension.height / 2 + boxedEntry.center.y + boxedEntry.dimension.height / 2, ) || condition( boxedEntry.center.x - boxedEntry.dimension.width / 2, - boxedEntry.center.y - boxedEntry.dimension.height / 2 - ) + boxedEntry.center.y - boxedEntry.dimension.height / 2, + ), ) .map(([quadrant]) => quadrant); } @@ -139,9 +159,12 @@ export class QuadTree { private realignObjects(): void { this.objects.forEach((boxedEntry) => { this.getQuadrants(boxedEntry).forEach((direction) => { - this.children - .get(direction) - .insert(boxedEntry.id, boxedEntry.dimension, boxedEntry.center); + const quadrant = this.children.get(direction); + quadrant?.insert( + boxedEntry.id, + boxedEntry.dimension, + boxedEntry.center, + ); }); }); @@ -149,6 +172,6 @@ export class QuadTree { } private hasChildren() { - return this.children && this.children.length > 0; + return this.children && this.children.size > 0; } } |