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

それがNormalize問題だったことがわかります。カメラのルックとアップ ベクトルを正規化するべきではありませんでした。私が使用しているスケールでは、歪みが大きすぎてヒット テストが正しく機能しません。

于 2011-07-26T11:54:11.400 に答える
1

これを 3D で機能させるには、光線からヒット テストまでを提供する必要があります。Visual3D と RayHitTestParameters を取る VisualTreeHelper.HitTest の正しいオーバーロードを使用します: http://msdn.microsoft.com/en-us/library/ms608751.aspx

于 2011-07-25T17:03:46.810 に答える