WPF 3D - 确定 ModelVisual3D 是否被剪切在其 Viewport3D 内

发布于 2024-07-16 10:02:42 字数 180 浏览 12 评论 0原文

我在 Viewport3D 中有一个立方体渲染,我需要知道一种方法来确定所有立方体是否对用户可见。

编辑:需要明确的是,..我不是在谈论剪裁,因为这里有近/远平面距离。 我的意思是立方体太高或太宽,无法适应相机的视野。

任何帮助将不胜感激!

提前致谢。

I have a cube rendering inside a Viewport3D and i need to know a way to find out whether ALL of the cube is visible to the user.

Edit:Just to be clear,..I'm not talking about clipping because of the near/far plane distance here. I mean the cube is to tall or wide to fit in the cameras field of view.

Any help would be massively appreciated!

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

全部不再 2024-07-23 10:02:42

我无法提供解决方案,但也许我可以为您指出正确的方向。

您需要掌握的是立方体在视图平面上的二维投影的范围。 然后,您可以对最小和最大 X & 进行简单检查。 Y 值可查看整个立方体是否可见。

在范围内添加容差因子将解决任何舍入误差。

编辑:我刚刚在 Google 上搜索了“2D 投影 WPF”和此链接出现了。 看起来它解决了你想要的问题。

进一步编辑:我从上面的链接复制了相关的代码部分。

public static Rect Get2DBoundingBox(ModelVisual3D mv3d)
{
    bool bOK;

    Matrix3D m = MathUtils.TryWorldToViewportTransform(vpv, out bOK);

    bool bFirst = true;    
    Rect r = new Rect();

    if (mv3d.Content is GeometryModel3D)
    {
        GeometryModel3D gm3d = (GeometryModel3D) mv3d.Content;

        if (gm3d.Geometry is MeshGeometry3D)
        {
            MeshGeometry3D mg3d = (MeshGeometry3D)gm3d.Geometry;

            foreach (Point3D p3d in mg3d.Positions)
            {
                Point3D pb = m.Transform(p3d);
                Point p2d = new Point(pb.X, pb.Y);
                if (bFirst)
                {
                    r = new Rect(p2d, new Size(1, 1));
                    bFirst = false;
                }
                else
                {
                    r.Union(p2d);
                }
            }
        }
    }

    return r;
}

I can't offer a solution but I can, perhaps, point you in the right direction.

What you need to get hold of is the extent of the 2D projection of the cube on the view plane. You can then do a simple check on the min and max X & Y values to see whether the whole of the cube is visible.

Adding a tolerance factor to the extent will take care of any rounding errors.

EDIT: I have just done a Google search for "2D projection WPF" and this link came up. It looks like it addresses what you want.

FURTHER EDIT: I've copied the relevant section of code from the above link here.

public static Rect Get2DBoundingBox(ModelVisual3D mv3d)
{
    bool bOK;

    Matrix3D m = MathUtils.TryWorldToViewportTransform(vpv, out bOK);

    bool bFirst = true;    
    Rect r = new Rect();

    if (mv3d.Content is GeometryModel3D)
    {
        GeometryModel3D gm3d = (GeometryModel3D) mv3d.Content;

        if (gm3d.Geometry is MeshGeometry3D)
        {
            MeshGeometry3D mg3d = (MeshGeometry3D)gm3d.Geometry;

            foreach (Point3D p3d in mg3d.Positions)
            {
                Point3D pb = m.Transform(p3d);
                Point p2d = new Point(pb.X, pb.Y);
                if (bFirst)
                {
                    r = new Rect(p2d, new Size(1, 1));
                    bFirst = false;
                }
                else
                {
                    r.Union(p2d);
                }
            }
        }
    }

    return r;
}
只涨不跌 2024-07-23 10:02:42

我记得 Flipcode 上有一个关于视锥体剔除的教程。

我希望它有帮助

I remember a tutorial on frustum culling on flipcode.

Flipcode - Frustum Culling

I hope it helps.

不弃不离 2024-07-23 10:02:42

我可以考虑做类似的事情:

检查与相机相关的立方体的最近点,并检查它是否从附近的剪切平面被剪切。
我能想到的距相机最近的点是构成立方体的点之一。 因此,您必须检查立方体的 6 个点中的每一个,并检查它们是否被剪裁。 如果都不是,那么你的立方体完全可见
哦,显然你还必须检查远剪裁平面。

代码很简单:

for each point of cube do
    if !(point is in farClippingPlane and nearClippingPlane)
       return false;
    end if
end for
return true

I can think of doing something similar to this:

Check the nearest point of the cube related to the camera and check if it's being clipped from the near clipping plane.
The nearest point from the camera I can think of is one of this points composing the cube. So you have to check each of the 6 points of the cube and check if they are being clipped. If none of them are, then your cube if fully visible
Oh, and obviously you have to check against the far clipping plane too.

The code is simple:

for each point of cube do
    if !(point is in farClippingPlane and nearClippingPlane)
       return false;
    end if
end for
return true
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文