src/octree/world/KeyIterator.js
- import { Vector3 } from "three";
-
- /**
- * A key range iterator.
- *
- * @implements {Iterator}
- * @implements {Iterable}
- */
-
- export class KeyIterator {
-
- /**
- * Constructs a new key iterator.
- *
- * This iterator returns all keys in the specified coordinate range, including
- * those at min and max.
- *
- * @param {KeyDesign} keyDesign - A key design.
- * @param {Vector3} min - The lower index bounds (zero-based unsigned integer coordinates).
- * @param {Vector3} max - The upper index bounds (zero-based unsigned integer coordinates).
- */
-
- constructor(keyDesign, min, max) {
-
- /**
- * The key design.
- *
- * @type {KeyDesign}
- * @private
- */
-
- this.keyDesign = keyDesign;
-
- /**
- * The lower index bounds.
- *
- * @type {Vector3}
- * @private
- */
-
- this.min = min;
-
- /**
- * The upper index bounds.
- *
- * @type {Vector3}
- * @private
- */
-
- this.max = max;
-
- /**
- * The base key coordinates.
- *
- * @type {Vector3}
- * @private
- */
-
- this.keyBase = new Vector3();
-
- /**
- * The current key iteration coordinates.
- *
- * @type {Vector3}
- * @private
- */
-
- this.key = new Vector3();
-
- /**
- * The iteration limits.
- *
- * @type {Vector3}
- * @private
- */
-
- this.limit = new Vector3();
-
- /**
- * An iterator result.
- *
- * @type {IteratorResult}
- * @private
- */
-
- this.result = {
- value: null,
- done: false
- };
-
- this.reset();
-
- }
-
- /**
- * Resets this iterator.
- *
- * @return {KeyIterator} This iterator.
- */
-
- reset() {
-
- const keyDesign = this.keyDesign;
- const min = this.min;
- const max = this.max;
-
- if(min.x <= max.x && min.y <= max.y && min.z <= max.z) {
-
- this.keyBase.set(min.x, min.y * keyDesign.rangeX, min.z * keyDesign.rangeXY);
- this.limit.set(max.x, max.y * keyDesign.rangeX, max.z * keyDesign.rangeXY);
- this.key.copy(this.keyBase);
-
- } else {
-
- // The range is invalid. Return no keys.
- this.keyBase.set(1, 1, 1);
- this.limit.set(0, 0, 0);
- this.key.copy(this.keyBase);
-
- console.error("Invalid key range", min, max);
-
- }
-
- this.result.value = null;
- this.result.done = false;
-
- return this;
-
- }
-
- /**
- * Iterates over the key range.
- *
- * @return {IteratorResult} The next key.
- */
-
- next() {
-
- const result = this.result;
- const keyDesign = this.keyDesign;
- const keyBase = this.keyBase;
- const limit = this.limit;
- const key = this.key;
-
- if(key.z <= limit.z) {
-
- // Put the key pieces together.
- result.value = key.z + key.y + key.x;
-
- // Advance the key coordinates.
- ++key.x;
-
- if(key.x > limit.x) {
-
- key.x = keyBase.x;
- key.y += keyDesign.rangeX;
-
- if(key.y > limit.y) {
-
- key.y = keyBase.y;
- key.z += keyDesign.rangeXY;
-
- }
-
- }
-
- } else {
-
- result.value = null;
- result.done = true;
-
- }
-
- return result;
-
- }
-
- /**
- * Called when this iterator will no longer be run to completion.
- *
- * @param {Object} value - An interator result value.
- * @return {IteratorResult} - A premature completion result.
- */
-
- return(value) {
-
- this.result.value = value;
- this.result.done = true;
-
- return this.result;
-
- }
-
- /**
- * Returns this iterator.
- *
- * @return {KeyIterator} An iterator.
- */
-
- [Symbol.iterator]() {
-
- return this;
-
- }
-
- }