繁体   English   中英

在C#中对Clipper感到困惑

[英]Confused on Clipper in C#

我正在Unity中创建一个2D游戏,该游戏已按程序放置了瓷砖。 我想使用安格斯·约翰逊(Angus Johnson)的Clipper库(特别是并集函数)简化碰撞几何,但是我遇到了一个问题,库返回空的解决方案,我不确定为什么。

作为参考,这是我一直在测试的多边形对撞机。 参考图片

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

    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(对于联合)返回一个空的解决方案。 我发现“ Clipper”类中的“ BuildResult”函数确实正在运行,并且“ m_PolyOuts”中包含数据,但是该列表中“ OutRec”的“ Pts”属性都为空。 我不知道这种情况发生在哪里,或者他们是否曾经设置过。

我坚信这是正确的行为,我只是在错误地使用库,但是我找不到任何文档或示例来说明我需要进行哪些更改才能使联合成功。

谢谢。

编辑:我已经缩小了一点。 在Clipper类的“ ExecuteInteral”期间,“ Pts”列表不会为空,直到运行“ FixupOutPolygon”函数。 之后,所有列表均为空。 “ JoinCommonEdges”还使几个列表为空,但不是全部。

我也一直在从事自己的游戏项目,偶然发现Clipper存在类似问题。 在这种情况下对我有用的是代替编写此代码:

clipper.Execute(ClipType.ctUnion, solution);

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM