HitTest3D
Windows Presentation Foundationの特徴の一つには3Dグラフィックスがあります。以前紹介したように3Dの描画自身はそれほど難しくはありません。3Dを使ったメニューのようなものを作りたいとき必要なことは、マウスによるクリックがどの3Dオブジェクトを選択したのかを確認することです。残念ながら、3Dオブジェクトにマウスクリックのコールバックを設定することはできません。
まず、Viewport3Dにマウスクリックのコールバックを設定します。WPFには、マウスがどのオブジェクトをクリックしたかを確認するためのVisualTreeHelper.HitTestメソッドがありますので、このコールバックの中でHitTestを呼び出します。
<Viewport3D MouseLeftButtonDown="OnClick" Name="myViewport3D" >
...
// Viewport3Dクリック時のヒットテスト
public void OnClick(object sender, System.Windows.Input.MouseButtonEventArgs args)
{
Point mouseposition = args.GetPosition(myViewport3D);
PointHitTestParameters pointparams =
new PointHitTestParameters(mouseposition);
VisualTreeHelper.HitTest(myViewport3D, null, HTResult, pointparams);
}
ここで注意してほしいのは、第4引数にHitTestParameters3DではなくPointHitTestParametersを渡している点です。これは第1引数にViewport3Dを渡しているからです。Viewport3Dは3Dを2Dに投影したスクリーンですから実は2Dのオブジェクトなのです。ここに3Dオブジェクトを渡そうとすると、自前でマウスのクリック点からレイを導出し、逆座標変換でスクリーン空間からワールド空間に変換し戻す必要があるので面倒です。
HitResult関数では、次のようにHitTestResultで渡されたオブジェクトと、判定したいオブジェクトの比較を行い、必要な作業を行います。ここではVisualHitを使いましたが、RayMeshGeometry3DHitTestResultのメンバには、MeshHit、ModelHit、PointHit、VisualHitなどがあり、目的に応じて利用できます。
public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult)
{
if (rawresult != null)
{
RayMeshGeometry3DHitTestResult rayMeshResult =
rawresult as RayMeshGeometry3DHitTestResult;
if (rayMeshResult != null)
{
Visual3D v3d = rayMeshResult.VisualHit as Visual3D;
if (v3d.Equals(myModel1))
{
myPanelStoryboardForward.Begin(myViewport3D);
}
else
{
MyVideoDrawing4.Player = null;
}
}
}
return HitTestResultBehavior.Stop;
}
また、ここでは一番手前のオブジェクトだけを使いたかったので、HitTestResultBehavior.Stopにしていますが、HitTestResultBehavior.Continueにすれば下にあるオブジェクトのヒットテストも行います。
Comments
Anonymous
December 13, 2007
これまでVisual3D の派生クラスは ModelVisual3D だけでしたが、3.5では次の図のように新しくUIElement3D と Viewport3DVisula2D が加わりました。今回はAnonymous
December 13, 2007
これまでVisual3D の派生クラスは ModelVisual3D だけでしたが、3.5では次の図のように新しくUIElement3D と Viewport3DVisula2D が加わりました。今回は