【问题标题】:WPF 3D - Fit ModelVisual3D into the camera's field of view?WPF 3D - 将 ModelVisual3D 适合相机的视野?
【发布时间】:2009-04-02 09:46:16
【问题描述】:

我有一个长方体,它的尺寸是从 XML 导入的,所以我需要确保无论模型的大小如何,相机都能看到它的全部。这是出于预览目的。为了清楚起见,我可能会在顶部显示比例尺。

我想我需要一些函数来告诉我 ModelVisual3D 是否适合相机的 FieldOfView 范围内,或者可能是 ViewPort3D 本身。

到目前为止,当尺寸属性更改时,我有静态回调(尺寸属性为DependencyPropertys),定义如下。目前它非常粗糙,但你明白我正在寻找的想法。注释掉的部分大致显示了我正在寻找什么样的逻辑

    private static void OnCubeDimensionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!valueSemaphore)
        {
            //while(mainModel.WillClip(mainCamera))
            //{
            //     mainCamera.FieldOfView--;
            //}

            valueSemaphore = true;
            double propertyValue = 0.0;
            Product3D p = d as Product3D;

            switch (e.Property.Name)
            {
                case "CubeHeight":
                    propertyValue = (double.Parse(e.NewValue.ToString()) / 100) * 8;
                    p.CubeHeight = propertyValue;
                    break;
                case "CubeWidth":
                    propertyValue = (double.Parse(e.NewValue.ToString()) / 100) * 5.3;
                    p.CubeWidth = propertyValue;
                    break;
                case "CubeDepth":
                    propertyValue = (double.Parse(e.NewValue.ToString()) / 100) * 2.6;
                    p.CubeDepth = propertyValue;
                    break;
            }
            valueSemaphore = false;
        }
    }

如果有人知道注释掉的部分应该放在哪里,我将永远感激不尽。
提前致谢。

【问题讨论】:

标签: wpf 3d modelvisual3d perspectivecamera fieldofview


【解决方案1】:

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

在该范围内添加容差因子将处理任何舍入错误。

我从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);
                }
            }
        }
    }

【讨论】:

    猜你喜欢
    • 2011-01-28
    • 2011-02-20
    • 2016-04-24
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多