2

我正在编写一个以 3D 显示地形的 WPF 应用程序。

当我执行命中测试时,返回了错误的 3D 点(不是我点击的点)。

我尝试突出显示被击中的三角形(通过创建一个新网格,从RayMeshGeometry3DHitTestResult对象中获取坐标)。我看到错误的三角形被击中(一个三角形被突出显示,但它不在光标下)。

我正在使用视场为 60 的透视相机,近平面和远平面分别为 3 和 35000。

知道为什么会发生以及我能做些什么来解决它吗?

如果您需要更多数据,请告诉我。

编辑:这是我用来执行命中测试的代码:

private void m_viewport3d_MouseDown(object sender, MouseButtonEventArgs e)
{
    Point mousePos = e.GetPosition(m_viewport3d);
    PointHitTestParameters hitParams = new PointHitTestParameters(mousePos);
    HitTestResult result = VisualTreeHelper.HitTest(m_viewport3d, mousePos);
    RayMeshGeometry3DHitTestResult rayMeshResult = result as RayMeshGeometry3DHitTestResult;
    if (rayMeshResult != null)
    {
        MeshGeometry3D mesh = new MeshGeometry3D();
        mesh.Positions.Add(rayMeshResult.MeshHit.Positions[rayMeshResult.VertexIndex1]);
        mesh.Positions.Add(rayMeshResult.MeshHit.Positions[rayMeshResult.VertexIndex2]);
        mesh.Positions.Add(rayMeshResult.MeshHit.Positions[rayMeshResult.VertexIndex3]);
        mesh.TriangleIndices.Add(0);
        mesh.TriangleIndices.Add(1);
        mesh.TriangleIndices.Add(2);
        GeometryModel3D marker = new GeometryModel3D(mesh, new DiffuseMaterial(Brushes.Blue));
        //...add marker to the scene...
    }
}
4

3 回答 3

3

让我印象深刻的是这些点在模型坐标中。我不得不转换为世界坐标。这是我进行命中测试的代码(这将返回光标下的所有命中,而不仅仅是第一个命中):

//  This will cast a ray from the point (on _viewport) along the direction that the camera is looking, and returns hits
private List<RayMeshGeometry3DHitTestResult> CastRay(Point clickPoint, IEnumerable<Visual3D> ignoreVisuals)
{
    List<RayMeshGeometry3DHitTestResult> retVal = new List<RayMeshGeometry3DHitTestResult>();

    //  This gets called every time there is a hit
    HitTestResultCallback resultCallback = delegate(HitTestResult result)
    {
        if (result is RayMeshGeometry3DHitTestResult)       //  It could also be a RayHitTestResult, which isn't as exact as RayMeshGeometry3DHitTestResult
        {
            RayMeshGeometry3DHitTestResult resultCast = (RayMeshGeometry3DHitTestResult)result;
            if (ignoreVisuals == null || !ignoreVisuals.Any(o => o == resultCast.VisualHit))
            {
                retVal.Add(resultCast);
            }
        }

        return HitTestResultBehavior.Continue;
    };

    //  Get hits against existing models
    VisualTreeHelper.HitTest(grdViewPort, null, resultCallback, new PointHitTestParameters(clickPoint));

    //  Exit Function
    return retVal;
}

还有一些消耗一击的逻辑:

if (hit.VisualHit.Transform != null)
{
    return hit.VisualHit.Transform.Transform(hit.PointHit);
}
else
{
    return hit.PointHit;
}
于 2012-03-31T15:42:58.003 回答
1

您需要提供射线来命中测试,以便它在 3d 中工作。使用 VisualTreeHelper.HitTest 的正确重载,它采用 Visual3D 和 RayHitTestParameters:http: //msdn.microsoft.com/en-us/library/ms608751.aspx

于 2011-07-25T17:03:46.810 回答
1

发现这是一个Normalize问题。我不应该标准化相机的外观和向上向量。在我使用的音阶中,失真太大,命中测试无法正常工作。

于 2011-07-26T11:54:11.400 回答