第三篇:实践篇 《使用Assembler 实现图片任意切割功能》

第三篇:实践篇 《使用Assembler 实现图片任意切割功能》_第1张图片

实现原理:

共用一个texture、material、渲染状态等。紧通过修改vertex、uvs、indexes数据即可实现任意切割功能。

一、线段分割多边形,并分散多边形

  • 线段分割多边形

已知多边形points,线段sp、ep。线段分割多边形得到两个多边形。

public splitPolygon(
    points: cc.Vec2[],
    sp: cc.Vec2,
    ep: cc.Vec2
  ): cc.Vec2[][] {
    console.log(points);

    let intersectCount = 0;
    const polygon1 = [];
    const polygon2 = [];

    for (let i = 0; i < points.length; i++) {
      const p1 = points[i];
      const p2 = points[(i + 1) % points.length];
      this.convertToInt([p1, p2]);
      if (intersectCount === 0) {
        polygon1.push(p1);
      } else if (intersectCount === 1) {
        polygon2.push(p1);
      } else if (intersectCount === 2) {
        polygon1.push(p1);
      }
      const point = segmentIntersect(sp, ep, p1, p2);

      if (point !== null) {
        this.convertToInt([point]);
        polygon1.push(point);
        polygon2.push(point);
        intersectCount++;
      }
    }
    if (intersectCount === 2) {
      return [polygon1, polygon2];
    }
    return [polygon1];
  }
  • 获得多边形数组创建成sprite 

//分割多边形
  splitSprites(sprites: CustomSprite[]): void {
    for (let i = 0; i < sprites.length; i++) {
      console.log("第", i, "开始分割");
      const baseSprite = sprites[i];
      const points = baseSprite.getPolygon();
      const { sp, ep } = this.getLocalTouchEndPoint(baseSprite.node);
      const newPolygons = this.splitPolygon(points, sp, ep);
      newPolygons.forEach((polygon, i) => {
        if (i === 0) {
          baseSprite.setPolygon(polygon);
        } else {
          const node = new cc.Node();
          const sprite = node.addComponent(CustomSprite);
          sprite.texture2D = baseSprite.texture2D;
          node.parent = baseSprite.node.parent;
          node.position = baseSprite.node.position;
          sprite.setPolygon(polygon);
          this.customSprites.push(sprite);

          console.log("添加新的纹理");
          this.isDisperse = true;
        }
      });
    }
  }
  • 以线段为边界和几何中心点位置,把多边形分散

 //根据几何中心点拿到直线法向量分离
  disperseAllSprite(): void {
    if (!this.isDisperse) return;
    const { p1, p2 } = this.getGraphic();
    this.customSprites.forEach((sprite, i) => {
      const polygon = sprite.polygon;
      const centerP = calculatePolygonGeometryCenter(polygon);
      const wp = sprite.node.convertToWorldSpaceAR(centerP);
      const np = this.graphic.node.convertToNodeSpaceAR(wp);
      const pIntersect = pointLineNormal(np, p1, p2);
      const normal = pIntersect.normalize();
      sprite.node.x += normal.x * this.getDisperse();
      sprite.node.y += normal.y * this.getDisperse();

      sprite.setVertsDirty();

      // this.printPolygon(polygon);
    });
  }

二、Assembler自定义(vertex数据、uv数据、indexes数据)

第四篇:实践2 《使用MeshRender 实现图片任意切割功能》

你可能感兴趣的:(javascript,开发语言,ecmascript)