quadTree/cube/CubeEntityCollectionsTreeStrategy.tstypescript
import { Extent } from "../../Extent";
import type { Entity } from "../../entity/Entity";
import type { EntityCollection } from "../../entity/EntityCollection";
import type { Vector } from "../../layer/Vector";
import { CUBE_FACE_LINKS, CUBE_NODE_ID_OFFSET } from "../../proj/cube";
import { EntityCollectionsTreeStrategy } from "../EntityCollectionsTreeStrategy";
import type { QuadTreeStrategy } from "../QuadTreeStrategy";
import { CubeEntityCollectionNode } from "./CubeEntityCollectionNode";
/**
* Entity collections of a vector layer in six trees, one on each cube face. The nodes have the ids of the planet
* nodes with the same tiles, so a collection is drawn with the visible tile and its entities go down to its terrain.
* @class
* @extends {EntityCollectionsTreeStrategy}
*/
export class CubeEntityCollectionsTreeStrategy extends EntityCollectionsTreeStrategy {
protected _faceTrees: CubeEntityCollectionNode[];
constructor(quadTreeStrategy: QuadTreeStrategy, layer: Vector, nodeCapacity: number) {
super(quadTreeStrategy, layer, nodeCapacity);
const planet = layer._planet!;
this._faceTrees = CUBE_FACE_LINKS.map((_, face) => {
const root = new CubeEntityCollectionNode(
this,
0,
null,
Extent.createFromArray([face, 0, face + 1, 1]),
planet,
0
);
root.nodeId = CUBE_NODE_ID_OFFSET + face;
return root;
});
}
protected _getFace(entity: Entity): number {
const face = Math.floor(this._faceTrees[0].__setLonLat__(entity).lon);
return Math.min(Math.max(face, 0), this._faceTrees.length - 1);
}
protected _traverse(callback: (node: CubeEntityCollectionNode) => void) {
for (const tree of this._faceTrees) {
tree.traverseTree(callback);
}
}
public override insertEntity(entity: Entity, rightNow: boolean = false) {
this._faceTrees[this._getFace(entity)].insertEntity(entity, rightNow);
}
public override insertEntities(entitiesForTree: Entity[]) {
const faceEntities: Entity[][] = this._faceTrees.map(() => []);
for (const entity of entitiesForTree) {
faceEntities[this._getFace(entity)].push(entity);
}
this._faceTrees.forEach((tree, face) => tree.buildTree(faceEntities[face]));
}
public override setPickingEnabled(pickingEnabled: boolean) {
this._traverse((node) => node.entityCollection!.setPickingEnabled(pickingEnabled));
}
public override setReceiveProjectors(receiveProjectors: boolean) {
this._traverse((node) => node.entityCollection!.setReceiveProjectors(receiveProjectors));
}
public override setReceiveShadows(receiveShadows: boolean) {
this._traverse((node) => node.entityCollection!.setReceiveShadows(receiveShadows));
}
public override setReceiveFrameTransparency(receiveFrameTransparency: boolean) {
this._traverse((node) => node.entityCollection!.setReceiveFrameTransparency(receiveFrameTransparency));
}
public override dispose() {
this._faceTrees = [];
this._renderingNodes = {};
}
public override collectVisibleEntityCollections(outArr: EntityCollection[]) {
const visibleNodes = this.quadTreeStrategy._visibleNodes;
this._renderingNodes = {};
this._secondPASS = [];
for (const tree of this._faceTrees) {
tree.collectRenderCollectionsPASS1(visibleNodes, outArr);
}
let i = this._secondPASS.length;
while (i--) {
this._secondPASS[i].collectRenderCollectionsPASS2(visibleNodes, outArr, this._secondPASS[i].nodeId);
}
}
}