const fetch = require("node-fetch"); const context = require("./context"); const bs = require("./boundingSphere"); const Intersect = require("./intersect"); const screenSpace = require("./screenSpace"); const Nodes = require("./nodes"); class Traverse { constructor() { this.stack = []; this.nodes = new Nodes(); } async begin(req, layer) { let ctx = context.fromRequest(req); ctx.layer = layer; let rootNode = `${layer}/nodes/root`; this.stack.push(fetch(rootNode)); while (this.stack.length > 0) { let currentResponses = await Promise.all(this.stack); let currentNodes = await Promise.all(currentResponses.map(node => node.json())); this.stack = currentNodes.reduce((accumulator, node) => { if (this.shouldDescend(ctx, node)) { accumulator.push(...node.children.map(child => fetch(`${layer}/nodes/${child.id}`))); } return accumulator; }, []); } return this.nodes.sorted; } shouldDescend(ctx, child) { let boundingSphere = bs.fromArray(child.mbs); if (ctx.cullingVolume.computeVisibility(boundingSphere) == Intersect.OUTSIDE) { return false; } let maxError = child.lodSelection[0].maxError; let screenSpaceError = screenSpace.screenSpaceError(ctx, boundingSphere); if (screenSpaceError >= maxError && child.children) { return true; } this.nodes.add(ctx, child, boundingSphere); return false; } } module.exports = Traverse;