traverse.js 1.51 KB
Newer Older
Athanasios's avatar
Athanasios committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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;