From f96e143558dff846c9afd857aa25e1fddedd3232 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 7 Oct 2023 13:11:27 +0500 Subject: [PATCH] Refactor tree --- lib/physics/common/boundary.js | 10 +++++++++ lib/physics/common/tree.js | 40 ++++++++++++++++++++-------------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/lib/physics/common/boundary.js b/lib/physics/common/boundary.js index f4cb575..8c3d593 100644 --- a/lib/physics/common/boundary.js +++ b/lib/physics/common/boundary.js @@ -116,4 +116,14 @@ export class BoundaryBox { return new BoundaryBox(left, right, top, bottom); } + + /** + * @param {BoundaryBox} b1 + * @param {BoundaryBox} b2 + * @return {boolean} + */ + static isEqual(b1, b2) { + return b1.left === b2.left && b1.right === b2.right + && b1.top === b1.top && b2.bottom === b2.bottom; + } } \ No newline at end of file diff --git a/lib/physics/common/tree.js b/lib/physics/common/tree.js index 6e8a863..69f8f6f 100644 --- a/lib/physics/common/tree.js +++ b/lib/physics/common/tree.js @@ -64,11 +64,31 @@ export class SpatialTree { } #fillLeaf(current) { - const {items, segmentBoundary: boundary} = current; - if (items.length <= this.maxCount) { - return; + if (current.items.length <= this.maxCount) return; + + for (const segmentBoundary of this.#iterateSegments(current.segmentBoundary)) { + const leaf = this.#createLeaf(current, segmentBoundary, current.items); + if (leaf !== null) { + current.addLeaf(leaf) + } } + for (const leaf of current.leafs) { + this.#fillLeaf(leaf); + } + } + + #createLeaf(parent, segmentBoundary, items) { + const filteredItems = items.filter(b => !b.static && SpatialTree.#isContainedByBoundary(b, segmentBoundary)); + if (filteredItems.length <= 0) return null; + + const boundaryBox = BoundaryBox.fromBodies(filteredItems, BoundaryBoxPool); + const containsActive = parent.containsActive && filteredItems.some(b => b.active); + + return new SpatialLeaf(this.#leafId++, filteredItems, boundaryBox, segmentBoundary, containsActive); + } + + * #iterateSegments(boundary) { if (boundary.width <= EPSILON && boundary.height <= EPSILON) { return; } @@ -84,21 +104,9 @@ export class SpatialTree { const top = boundary.top + y * yStep; const bottom = (y < this.divider - 1 ? top + yStep : boundary.bottom + EPSILON); - const segmentBoundary = BoundaryBoxPool.get().update(left, right, top, bottom); - const filteredItems = items.filter(b => !b.static && SpatialTree.#isContainedByBoundary(b, segmentBoundary)); - - if (filteredItems.length > 0) { - const boundaryBox = BoundaryBox.fromBodies(filteredItems, BoundaryBoxPool); - const containsActive = current.containsActive && filteredItems.some(b => b.active); - const leaf = new SpatialLeaf(this.#leafId++, filteredItems, boundaryBox, segmentBoundary, containsActive); - current.addLeaf(leaf); - } + yield BoundaryBoxPool.get().update(left, right, top, bottom); } } - - for (const leaf of current.leafs) { - this.#fillLeaf(leaf); - } } free() {