"use strict";
cc._RF.push(module, '0e7bcbZcTlDpq0EVxPZXBR0', 'PhysicsPolygonColliderEx');
// TypeScript2/PhysicsPolygonColliderEx.ts

Object.defineProperty(exports, "__esModule", { value: true });
var THICK = 100;
var gfx = cc['gfx'];
var _a = cc._decorator, ccclass = _a.ccclass, property = _a.property, menu = _a.menu, requireComponent = _a.requireComponent;
var PhysicsPolygonColliderEx = /** @class */ (function (_super) {
    __extends(PhysicsPolygonColliderEx, _super);
    function PhysicsPolygonColliderEx() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.meshRenderer = null;
        _this._polys = [];
        _this._physicsPolygonColliders = [];
        _this._commands = [];
        return _this;
    }
    Object.defineProperty(PhysicsPolygonColliderEx.prototype, "polys", {
        get: function () {
            var _this = this;
            return this._polys.map(function (v) { return _this._convertClipperPathToVecArray(v); });
        },
        enumerable: false,
        configurable: true
    });
    PhysicsPolygonColliderEx.prototype.init = function (polys) {
        var _this = this;
        this._polys = polys.map(function (v) { return _this._convertVecArrayToClipperPath(v); });
        this._commands = [];
    };
    PhysicsPolygonColliderEx.prototype.pushCommand = function (name, params) {
        this._commands.push({ name: name, params: params });
    };
    PhysicsPolygonColliderEx.prototype.polyDifference = function (poly, ctx) {
        // if (poly.length < 3) return;
        var _this = this;
        // 计算新的多边形
        var cpr = new ClipperLib.Clipper(ClipperLib.Clipper.ioStrictlySimple); //ClipperLib.Clipper.ioStrictlySimple | ClipperLib.Clipper.ioPreserveCollinear
        // cpr.PreserveCollinear = true;
        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);
        // cc.log(solution_expolygons);
        // 将多边形分割成三角形 并绘制出来
        ctx && ctx.clear(true);
        var _physicsPolygonColliders_count = 0;
        var _loop_1 = function (expolygon) {
            // const outers = ClipperLib.Clipper.SimplifyPolygon(expolygon.outer,ClipperLib.PolyFillType.pftEvenOdd);
            // cc.log(outer,"outer",expolygon.outer)
            var countor = this_1._convertClipperPathToPoly2triPoint(expolygon.outer);
            if (countor.length < 2)
                return "continue";
            var swctx = new poly2tri.SweepContext(countor, { cloneArrays: true });
            // const exclude = countor;
            var holes = expolygon.holes.map(function (h) { return _this._convertClipperPathToPoly2triPoint(h, countor); });
            try {
                // 防止 addhole 失败 使用try
                swctx.addHoles(holes);
                swctx.triangulate();
                var triangles = swctx.getTriangles();
                // cc.log('triangles', triangles);
                for (var _i = 0, triangles_1 = triangles; _i < triangles_1.length; _i++) {
                    var tri = triangles_1[_i];
                    // 逐一处理三角形
                    var c = this_1._physicsPolygonColliders[_physicsPolygonColliders_count];
                    if (!c) {
                        c = this_1.addComponent(cc.PhysicsPolygonCollider);
                        c.friction = 0;
                        c.restitution = 0;
                        this_1._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";
            }
        };
        var this_1 = this;
        for (var _i = 0, solution_expolygons_1 = solution_expolygons; _i < solution_expolygons_1.length; _i++) {
            var expolygon = solution_expolygons_1[_i];
            _loop_1(expolygon);
        }
        this._physicsPolygonColliders.slice(_physicsPolygonColliders_count).forEach((function (v) {
            if (v.points.length) {
                v.points.length = 0;
                v.apply();
            }
        }));
        // 绘制底层 mesh
        var arr2 = this._polys.map(function (v) { return _this._convertClipperPathToVecArray(v); });
        var poly_tri_arr = [];
        var c_count = arr2.length;
        for (var k = 0; k < c_count; k++) {
            var tmpArr = arr2[k];
            var tmpArr2 = [];
            for (var k2 = 0; k2 < tmpArr.length; k2++) {
                var aa = tmpArr[k2];
                tmpArr2.push([aa.x, aa.y]);
            }
            poly_tri_arr.push(tmpArr2);
        }
        this.addMesh(poly_tri_arr);
    };
    PhysicsPolygonColliderEx.prototype.addMesh = function (tri) {
        var allPoints = [];
        var indexArr = [];
        var uvIndexArr = [];
        var uvType = 0;
        var uvupTypeArr = [cc.v2(0, 0), cc.v2(0, 1), cc.v2(1, 0), cc.v2(1, 1)];
        var uvDownTypeArr = [cc.v2(1, 1), cc.v2(0, 0), cc.v2(0, 1), cc.v2(1, 0)];
        var colorIndex = [];
        // console.log("****2this._regions.length:"+tri.length);
        for (var i = 0; i < tri.length; i++) {
            var singleParr = [].concat(tri[i]);
            indexArr[i] = [];
            var length = singleParr.length;
            for (var j = 0; j < length; j++) {
                if (singleParr[j]) {
                    allPoints.push(cc.v3(singleParr[j][0], singleParr[j][1], 0));
                    indexArr[i].push(allPoints.length - 1);
                    uvIndexArr.push(uvupTypeArr[uvType]);
                    uvType = uvType >= 3 ? 0 : uvType + 1;
                    colorIndex.push(cc.Color.WHITE);
                }
            }
        }
        uvType = 0;
        var iLength = allPoints.length;
        for (var i = 0; i < iLength; i++) {
            allPoints[i + iLength] = cc.v3(allPoints[i].x, allPoints[i].y, -THICK);
            uvIndexArr.push(uvDownTypeArr[uvType]);
            uvType = uvType >= 3 ? 0 : uvType + 1;
            colorIndex.push(cc.Color.WHITE);
        }
        var vfmtPosColor = new gfx.VertexFormat([
            { name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 3 },
            { name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
            { name: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_UINT8, num: 4, normalize: true },
        ]);
        var mesh = new cc.Mesh();
        mesh.init(vfmtPosColor, allPoints.length, true);
        this.meshRenderer.mesh = mesh;
        mesh.setVertices(gfx.ATTR_POSITION, allPoints);
        mesh.setVertices(gfx.ATTR_COLOR, colorIndex);
        mesh.setVertices(gfx.ATTR_UV0, uvIndexArr);
        var indices = this.conmuteIndices(indexArr, iLength);
        mesh.setIndices(indices);
    };
    PhysicsPolygonColliderEx.prototype.conmuteIndices = function (indexArr, length) {
        var indicesarr = [];
        for (var i = 0; i < indexArr.length; i++) {
            var arr = indexArr[i];
            for (var j = 0; j < arr.length; j++) {
                var p1 = void 0, p2 = void 0, p3 = void 0, p4 = void 0;
                if (j < arr.length - 1) {
                    p1 = arr[j];
                    p2 = arr[j + 1];
                    p3 = arr[j] + length;
                    p4 = arr[j + 1] + length;
                }
                else {
                    p1 = arr[j];
                    p2 = arr[0];
                    p3 = arr[j] + length;
                    p4 = arr[0] + length;
                }
                indicesarr.push(p1, p2, p4, p3, p4, p1);
            }
        }
        return indicesarr;
    };
    PhysicsPolygonColliderEx.prototype.lateUpdate = function (dt) {
        if (this._commands.length) {
            // 每帧执行命令队列
            for (var index = 0; index < Math.ceil(this._commands.length / 2 + 0.5); index++) {
                var cmd = this._commands.shift();
                if (cmd)
                    this[cmd.name].apply(this, cmd.params);
                else
                    break;
            }
        }
    };
    PhysicsPolygonColliderEx.prototype._convertVecArrayToClipperPath = function (poly) {
        return poly.map(function (p) { return { X: p.x, Y: p.y }; });
    };
    PhysicsPolygonColliderEx.prototype._convertClipperPathToVecArray = function (poly) {
        return poly.map(function (p) { return cc.v2(p.X, p.Y); });
    };
    PhysicsPolygonColliderEx.prototype._convertClipperPathToPoly2triPoint = function (poly, exclude) {
        if (exclude === void 0) { 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 [];
    };
    __decorate([
        property(cc.MeshRenderer)
    ], PhysicsPolygonColliderEx.prototype, "meshRenderer", void 0);
    PhysicsPolygonColliderEx = __decorate([
        ccclass,
        menu("i18n:MAIN_MENU.component.physics/Collider/PolygonEX-lamyoung.com"),
        requireComponent(cc.RigidBody)
    ], PhysicsPolygonColliderEx);
    return PhysicsPolygonColliderEx;
}(cc.Component));
exports.default = PhysicsPolygonColliderEx;

cc._RF.pop();