"use strict";
cc._RF.push(module, 'eab4fE4ObRBBYbAUGehBobl', 'PhysicsCollider');
// script/PhysicsCollider.js

"use strict";

function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } it = o[Symbol.iterator](); return it.next.bind(it); }

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(o); 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; }

cc.Class({
  "extends": cc.Component,
  properties: {// polys: {
    //     get: () => {
    //         return this._polys.map((v) => { return this._convertClipperPathToVecArray(v) });
    //     }
    // }
  },
  // LIFE-CYCLE CALLBACKS:
  onLoad: function onLoad() {
    //
    this.DIG_OPTIMIZE_SIZE = 1; //

    this._commands = [];
    this._physicsPolygonColliders = [];
    this._polys = [[]];
  },
  // get polys() {
  //     return this._polys.map((v) => { return this._convertClipperPathToVecArray(v) });
  // },
  start: function start() {},
  _convertClipperPathToVecArray: function _convertClipperPathToVecArray(poly) {
    return poly.map(function (p) {
      return cc.v2(p.X, p.Y);
    });
  },
  _convertVecArrayToClipperPath: function _convertVecArrayToClipperPath(poly) {
    return poly.map(function (p) {
      return {
        X: p.x,
        Y: p.y
      };
    });
  },
  _convertClipperPathToPoly2triPoint: function _convertClipperPathToPoly2triPoint(poly, exclude) {
    // return poly.map((p) => { return new poly2tri.Point(p.X, p.Y) });
    var newPos = [];
    poly.forEach(function (p, i) {
      var p_now = new poly2tri.Point(p.X, p.Y);
      var isIn = exclude.some(function (e_p) {
        if (e_p.equals(p_now)) {
          return true;
        }
      });

      if (!isIn) {
        newPos.push(p_now);
        exclude.push(p_now);
      }
    });
    if (newPos.length > 2) return newPos;else return [];
  },
  init: function init(polys) {
    var _this = this;

    this._polys = polys.map(function (v) {
      return _this._convertVecArrayToClipperPath(v);
    });
    this._commands = [];
  },
  polyDifference: function polyDifference(poly, ctx) {
    var _this2 = this;

    if (!ctx) {
      cc.error("no ctx");
    }

    var cpr = new ClipperLib.Clipper();
    var subj_paths = this._polys;
    var clip_paths = [this._convertVecArrayToClipperPath(poly)];
    cpr.AddPaths(subj_paths, ClipperLib.PolyType.ptSubject, true);
    cpr.AddPaths(clip_paths, ClipperLib.PolyType.ptClip, true);
    var subject_fillType = ClipperLib.PolyFillType.pftEvenOdd;
    var clip_fillType = ClipperLib.PolyFillType.pftEvenOdd;
    var solution_polytree = new ClipperLib.PolyTree();
    cpr.Execute(ClipperLib.ClipType.ctDifference, solution_polytree, subject_fillType, clip_fillType);
    var solution_expolygons = ClipperLib.JS.PolyTreeToExPolygons(solution_polytree);
    this._polys = ClipperLib.Clipper.PolyTreeToPaths(solution_polytree); //

    ctx && ctx.clear(true);
    var _physicsPolygonColliders_count = 0;

    var _loop = function _loop() {
      var expolygon = _step.value;

      // let outers = ClipperLib.Clipper.SimplifyPolygon(expolygon.outer,ClipperLib.PolyFillType.pftEvenOdd);
      // cc.log(outer,"outer",expolygon.outer)
      var countor = _this2._convertClipperPathToPoly2triPoint(expolygon.outer);

      if (countor.length < 2) return "continue";
      var swctx = new poly2tri.SweepContext(countor, {
        cloneArrays: true
      }); // let exclude = countor;

      var holes = expolygon.holes.map(function (h) {
        return _this2._convertClipperPathToPoly2triPoint(h, countor);
      });

      try {
        // 防止 addhole 失败 使用try
        swctx.addHoles(holes);
        swctx.triangulate();
        var triangles = swctx.getTriangles();

        for (var _iterator2 = _createForOfIteratorHelperLoose(triangles), _step2; !(_step2 = _iterator2()).done;) {
          var tri = _step2.value;
          // 逐一处理三角形
          var c = _this2._physicsPolygonColliders[_physicsPolygonColliders_count];

          if (!c) {
            c = _this2.addComponent(cc.PhysicsPolygonCollider);
            c.friction = 0;
            c.restitution = 0;
            _this2._physicsPolygonColliders[_physicsPolygonColliders_count] = c;
          }

          c.points = tri.getPoints().map(function (v, i) {
            if (ctx) {
              if (i === 0) ctx.moveTo(v.x, v.y);else ctx.lineTo(v.x, v.y);
            }

            return cc.v2(v.x, v.y);
          });
          c.apply();
          _physicsPolygonColliders_count++;

          if (ctx) {
            ctx.close();
            ctx.fill();
          }
        }
      } catch (e) {
        console.error('polyDifference poly2tri error', _physicsPolygonColliders_count, expolygon);
        console.error(e);
        return "continue";
      }
    };

    for (var _iterator = _createForOfIteratorHelperLoose(solution_expolygons), _step; !(_step = _iterator()).done;) {
      var _ret = _loop();

      if (_ret === "continue") continue;
    }

    this._physicsPolygonColliders.slice(_physicsPolygonColliders_count).forEach(function (v) {
      if (v.points.length) {
        v.points.length = 0;
        v.apply();
      }
    });
  },
  pushCommand: function pushCommand(name, params) {
    this._commands.push({
      name: name,
      params: params
    });
  },
  lateUpdate: function lateUpdate(dt) {
    if (this._commands.length) {
      // 每帧执行命令队列
      for (var index = 0; index < 2; index++) {
        var cmd = this._commands.shift();

        if (cmd) this[cmd.name].apply(this, cmd.params);else break;
      }
    }
  } // update (dt) {},

});

cc._RF.pop();