"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var THREE = _interopRequireWildcard(require("three"));

function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function () {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

// Create an A(xis)A(ligned)B(ounding)B(ox) for the child `childIndex` of one aabb.
// (PotreeConverter protocol builds implicit octree hierarchy by applying the same
// subdivision algo recursively)
var dHalfLength = new THREE.Vector3();

var PotreeNode = /*#__PURE__*/function () {
  function PotreeNode() {
    var numPoints = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
    var childrenBitField = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var layer = arguments.length > 2 ? arguments[2] : undefined;
    (0, _classCallCheck2["default"])(this, PotreeNode);
    this.numPoints = numPoints;
    this.childrenBitField = childrenBitField;
    this.children = [];
    this.layer = layer;
    this.name = '';
    this.bbox = new THREE.Box3();
    this.sse = -1;
    this.baseurl = layer.source.baseurl;
  }

  (0, _createClass2["default"])(PotreeNode, [{
    key: "add",
    value: function add(node, indexChild, root) {
      this.children.push(node);
      node.parent = this;
      node.name = this.name + indexChild;
      this.createChildAABB(indexChild, node.bbox);

      if (node.name.length % this.layer.hierarchyStepSize == 0) {
        node.baseurl = "".concat(root.baseurl, "/").concat(node.name.substr(root.name.length));
      } else {
        node.baseurl = root.baseurl;
      }
    }
  }, {
    key: "createChildAABB",
    value: function createChildAABB(childIndex, box) {
      // Code inspired from potree
      box.copy(this.bbox);
      this.bbox.getCenter(box.max);
      dHalfLength.copy(box.max).sub(this.bbox.min);

      if (childIndex === 1) {
        box.min.z += dHalfLength.z;
        box.max.z += dHalfLength.z;
      } else if (childIndex === 3) {
        box.min.z += dHalfLength.z;
        box.max.z += dHalfLength.z;
        box.min.y += dHalfLength.y;
        box.max.y += dHalfLength.y;
      } else if (childIndex === 0) {//
      } else if (childIndex === 2) {
        box.min.y += dHalfLength.y;
        box.max.y += dHalfLength.y;
      } else if (childIndex === 5) {
        box.min.z += dHalfLength.z;
        box.max.z += dHalfLength.z;
        box.min.x += dHalfLength.x;
        box.max.x += dHalfLength.x;
      } else if (childIndex === 7) {
        box.min.add(dHalfLength);
        box.max.add(dHalfLength);
      } else if (childIndex === 4) {
        box.min.x += dHalfLength.x;
        box.max.x += dHalfLength.x;
      } else if (childIndex === 6) {
        box.min.y += dHalfLength.y;
        box.max.y += dHalfLength.y;
        box.min.x += dHalfLength.x;
        box.max.x += dHalfLength.x;
      }
    }
  }, {
    key: "getChildByName",
    value: function getChildByName(name) {
      if (this.name === name) {
        return this;
      }

      var charIndex = this.name.length;

      var _iterator = _createForOfIteratorHelper(this.children),
          _step;

      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          var child = _step.value;

          if (child.name[charIndex] == name[charIndex]) {
            return child.getChildByName(name);
          }
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }

      throw new Error("Cannot find node with name '".concat(name, "'"));
    }
  }, {
    key: "load",
    value: function load() {
      // Query octree/HRC if we don't have children potreeNode yet.
      if (!this.octreeIsLoaded) {
        this.loadOctree();
      }

      return this.layer.source.fetcher(this.url, this.layer.source.networkOptions).then(this.layer.source.parse);
    }
  }, {
    key: "loadOctree",
    value: function loadOctree() {
      var _this = this;

      var octreeUrl = "".concat(this.baseurl, "/r").concat(this.name, ".").concat(this.layer.source.extensionOctree);
      return this.layer.source.fetcher(octreeUrl, this.layer.source.networkOptions).then(function (blob) {
        var view = new DataView(blob);
        var stack = [];
        var offset = 0;
        _this.childrenBitField = view.getUint8(0);
        offset += 1;
        _this.numPoints = view.getUint32(1, true);
        offset += 4;
        stack.push(_this);

        while (stack.length && offset < blob.byteLength) {
          var snode = stack.shift(); // look up 8 children

          for (var indexChild = 0; indexChild < 8; indexChild++) {
            // does snode have a #indexChild child ?
            if (snode.childrenBitField & 1 << indexChild && offset + 5 <= blob.byteLength) {
              var childrenBitField = view.getUint8(offset);
              offset += 1;

              var numPoints = view.getUint32(offset, true) || _this.numPoints;

              offset += 4;
              var item = new PotreeNode(numPoints, childrenBitField, _this.layer);
              snode.add(item, indexChild, _this);
              stack.push(item);
            }
          }
        }
      });
    }
  }, {
    key: "octreeIsLoaded",
    get: function get() {
      return !(this.childrenBitField && this.children.length === 0);
    }
  }, {
    key: "url",
    get: function get() {
      return "".concat(this.baseurl, "/r").concat(this.name, ".").concat(this.layer.source.extension);
    }
  }]);
  return PotreeNode;
}();

var _default = PotreeNode;
exports["default"] = _default;