"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;
var _cesium = require("cesium");
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
// 三维模型裁剪
var Cut = /*#__PURE__*/function () {
  function Cut(tileset, opt) {
    _classCallCheck(this, Cut);
    if (!tileset) {
      console.log("缺少模型");
      return;
    }
    this.tileset = tileset;
    this.opt = opt || {};
    /**
     * @property {Boolean} iscutOutter 是否为外部裁剪，默认为内部裁剪
     */
    this._iscutOutter = this.opt.iscutOutter; // 是否为外部裁剪  默认为内部裁剪
    this.cutRegions = []; // 当前裁剪面数组对象
    /* this.modelMatrix = new Matrix4(); // 世界坐标系--》模型坐标系
    Matrix4.inverseTransformation(this.tileset.root.computedTransform, this.modelMatrix) */
    // 建立模型中心点坐标系
    var center = this.tileset.boundingSphere.center;
    var enuMtx4 = _cesium.Transforms.eastNorthUpToFixedFrame(center);
    this.modelMatrix = _cesium.Matrix4.inverse(enuMtx4, new _cesium.Matrix4());
    this.canvas = undefined;
  }
  return _createClass(Cut, [{
    key: "iscutOutter",
    get: function get() {
      return this._iscutOutter;
    },
    set: function set(val) {
      this._iscutOutter = val;
      this.updateShader();
    }

    /**
     * 添加裁剪面
     * @param {Object} attr 参数
     * @param {Cartesian3[]} attr.positions 压平面坐标
     * @param {Number} attr.id 唯一标识
     */
  }, {
    key: "addRegion",
    value: function addRegion(attr) {
      var _ref = attr || {},
        positions = _ref.positions,
        id = _ref.id;
      if (!id) id = new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0);
      if (!positions || positions.length < 3) {
        console.log("缺少裁剪面坐标");
        return;
      }
      var index = this.cutRegions.findIndex(function (item) {
        return item.id === id;
      });
      if (index == -1) {
        this.cutRegions.push({
          id: id,
          positions: positions
        });
      } else {
        this.cutRegions[index].positions = positions;
      }
      this.updateShader();
    }
    /**
     * 移除裁剪面
     * @param {String} id
     */
  }, {
    key: "removeRegionById",
    value: function removeRegionById(id) {
      if (id) {
        // 表示移除所有的裁剪面
        var index = this.cutRegions.findIndex(function (item) {
          return item.id === id;
        });
        if (index != -1) this.cutRegions.splice(index, 1);
      } else {
        // 表示移除单个的裁剪面
        this.cutRegions = [];
      }
      this.updateShader();
    }

    /**
     * 销毁
     */
  }, {
    key: "destroy",
    value: function destroy() {
      this.tileset.customShader = undefined;
    }

    /**
     * 修改模型着色器
     */
  }, {
    key: "updateShader",
    value: function updateShader() {
      var _this = this;
      // 定义着色器中裁剪函数
      var fs_textureMapRect = "\n            vec4 textureMapRect(vec4 rect, sampler2D map, vec2 xy) {\n                // \u5224\u65AD\u5F53\u524D\u56FE\u5143\u5750\u6807\u548C\u591A\u8FB9\u5F62\u5173\u7CFB \u5982\u679C\u5728\u591A\u8FB9\u5F62\u5185 \u8FDB\u884C\u7EB9\u7D20\u62FE\u53D6\n                if (xy.x >= rect.x && xy.x <= rect.z && xy.y >= rect.y && xy.y <= rect.w) {\n                    float w = rect.z - rect.x;\n                    float h = rect.w - rect.y;\n                    float s = (xy.x - rect.x) / w;\n                    float t = (xy.y - rect.y) / h;\n                    vec4 color = texture(map, vec2(s, 1.0 - t));\n                    return color;\n                }\n                return vec4(1.0);\n            }\n        ";
      var allUniforms = {
        u_inverseModel: {
          type: _cesium.UniformType.MAT4,
          value: this.modelMatrix.clone()
        },
        u_unionCutRegions: {
          type: _cesium.UniformType.BOOL,
          value: this._iscutOutter
        }
      };

      // 构建多区域着色器
      var fs = "";
      this.cutRegions.forEach(function (element) {
        var uniforms = _this.createUniforms(element.positions, element.id);
        allUniforms = (0, _cesium.combine)(allUniforms, uniforms);
        fs += "\n                vec4 color_".concat(element.id, " = textureMapRect(u_rect_").concat(element.id, ", u_map_").concat(element.id, ", xy);\n                cutColor *= color_").concat(element.id, ";\n            ");
      });
      fs += "\n            if (u_unionCutRegions) {\n                material.diffuse *= (vec3(1.0) - cutColor.rgb);\n            } else {\n                material.diffuse *= cutColor.rgb;\n            }\n            if (material.diffuse.r <= 0.0001 && material.diffuse.g <= 0.0001 && material.diffuse.b <= 0.0001) {\n                discard;\n            }\n        ";
      this.tileset.customShader = new _cesium.CustomShader({
        uniforms: allUniforms,
        fragmentShaderText: "\n            ".concat(fs_textureMapRect, "\n            void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {\n                vec4 positionMC = u_inverseModel * vec4(fsInput.attributes.positionWC, 1.0);\n                vec2 xy = positionMC.xy;\n                vec4 cutColor = vec4(1.0);\n                ").concat(fs, "\n            }")
      });
    }

    /**
     * 根据坐标创建片元着色器
     * @param {Cartesian3[]} positions
     * @param {String} id
     */
  }, {
    key: "createUniforms",
    value: function createUniforms(positions, id) {
      var _this2 = this;
      if (!positions || positions.length < 3) {
        console.log("缺少裁剪面坐标");
        return;
      }
      id = id || Math.ceil(Math.random() * 100000) + '_' + Math.ceil(Math.random() * 100000);
      // 根据世界坐标范围计算相对模型坐标范围
      var xs = [],
        ys = [],
        zs = [];
      // 计算模型坐标系下坐标
      var modelPoints = positions.map(function (p) {
        var point = _cesium.Matrix4.multiplyByPoint(_this2.modelMatrix, p, new _cesium.Cartesian3());
        xs.push(point.x);
        ys.push(point.y);
        zs.push(point.z);
        return point;
      });
      // 计算当前裁剪面边界范围（模型坐标系下）
      var rect = new _cesium.Cartesian4(Math.min.apply(null, xs), Math.min.apply(null, ys), Math.max.apply(null, xs), Math.max.apply(null, ys));
      var canvas = document.createElement('canvas');
      canvas.width = 1024;
      canvas.height = 1024;
      var width = rect.z - rect.x;
      var height = rect.w - rect.y;
      var ctx = canvas.getContext('2d');
      ctx.fillStyle = '#fff'; // 设置整体背景为白色
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.beginPath();
      ctx.moveTo(canvas.width * (modelPoints[0].x - rect.x) / width, canvas.height * (modelPoints[0].y - rect.y) / height);
      for (var i = 1; i < modelPoints.length; i++) {
        ctx.lineTo(canvas.width * (modelPoints[i].x - rect.x) / width, canvas.height * (modelPoints[i].y - rect.y) / height);
      }
      ctx.closePath();
      ctx.fillStyle = '#000'; // 根据填充的黑色来裁剪模型
      ctx.fill();
      this.canvas = canvas;
      var uniforms = {};
      uniforms["u_rect_".concat(id)] = {
        type: _cesium.UniformType.VEC4,
        value: rect
      };
      uniforms["u_map_".concat(id)] = {
        type: _cesium.UniformType.SAMPLER_2D,
        value: new _cesium.TextureUniform({
          url: canvas.toDataURL()
        }),
        minificationFilter: _cesium.TextureMinificationFilter.LINEAR,
        magnificationFilter: _cesium.TextureMagnificationFilter.LINEAR
      };
      return uniforms;
    }
  }]);
}();
var _default = exports["default"] = Cut;
//# sourceMappingURL=Cut.js.map
