感到困惑于C#中的Clipper

时间:2017-08-03 18:56:17

标签: c# unity3d clipperlib

我在Unity中创建了一个2D程序,它在程序上放置了瓷砖。我想使用Angus Johnson的Clipper库(特别是union函数)来简化碰撞几何,但是我遇到了库返回空解决方案的问题,我不知道为什么。< / p>

作为参考,这里是我用来测试的多边形碰撞器。 reference image

这是我用来组合几何的函数的简化版本:

    List<List<Vector2>> unitedPolygons = new List<List<Vector2>>();
    Clipper clipper = new Clipper();
    Paths solution = new Paths();
    ClipperOffset offset = new ClipperOffset();

    //Use a scaling factor for floats and convert the Polygon Colliders' points to Clipper's desired format
    int scalingFactor = 10000;
    for (int i = 0; i < polygons.Count; i++)
    {
        Path allPolygonsPath = new Path(polygons[i].points.Length);

        for (int j = 0; j < polygons[i].points.Length; j++)
        {
            allPolygonsPath.Add(new IntPoint(Mathf.Floor(polygons[i].points[j].x * scalingFactor), Mathf.Floor(polygons[i].points[j].y * scalingFactor)));
        }
        bool succeeded = clipper.AddPath(allPolygonsPath, PolyType.ptSubject, true);
    }

    //Execute the union
    bool success = clipper.Execute(ClipType.ctUnion, solution);
    Debug.Log("Polygons after union: " + solution.Count);

    //Offset the polygons
    offset.AddPaths(solution, JoinType.jtMiter, EndType.etClosedPolygon);
    offset.Execute(ref solution, 5f);

    //Convert back to a format Unity can use
    foreach (Path path in solution)
    {
        List<Vector2> unitedPolygon = new List<Vector2>();
        foreach (IntPoint point in path)
        {
            unitedPolygon.Add(new Vector2(point.X / (float)scalingFactor, point.Y / (float)scalingFactor));
        }
        unitedPolygons.Add(unitedPolygon);
    }

    return unitedPolygons;

我通过调试发现的是第一个Execute(对于union)返回一个空的解决方案。我已经发现&#34; BuildResult&#34;功能在&#34; Clipper&#34; class确实在运行,并且&#34; m_PolyOuts&#34;有数据,但是&#34; Pts&#34;该列表中&#34; OutRec&#34;的属性都为空。我无法弄清楚这种情况发生在哪里,或者它们是否曾被置于首位。

我确信这是正确的行为,我只是错误地使用了这个库,但是我无法找到任何文档或示例来解释我需要更改的内容以使联合成功。< / p>

感谢。

编辑:我把它缩小了一点。在&#34; ExecuteInteral&#34;在Clipper课程中,&#34; Pts&#34;列表在&#34; FixupOutPolygon&#34;之前是空的。功能运行。之后,所有列表都为空。 &#34; JoinCommonEdges&#34;还会使一些列表为null,但不是全部。

1 个答案:

答案 0 :(得分:0)

我一直在研究我自己的游戏项目,偶然发现了与Clipper类似的问题。在这种情况下对我有用的不是写这个:

clipper.Execute(ClipType.ctUnion, solution);

...我为Execute方法指定了PolyFillType:

clipper.Execute(ClipType.ctUnion, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

我不确定为什么它对我有用,但我认为这是因为某些路径可以共享公共边缘,因此默认的pftEvenOdd填充规则会被删除。