ContainerUIElement3DとModelUIElement3D

.NET Framework 3.5では.NET Framework 3.0部分の機能強化も行われており、WPFにおいてもいくつかの機能が追加されています。

WPF3D Team Blog : What’s new in WPF 3.5



上記のblogの内容から、まずはContainerUIElement3DとModelUIElement3Dがどのようなものであるかを簡単に説明したいと思います。


.NET Framework 3.0のWPFでは、3Dオブジェクトにおけるイベントは提供されていませんでした。そのため、たとえば3Dオブジェクトのこの部分がマウスでクリックされたらといった処理を書く場合、最上位のViewport3DオブジェクトでMouseLeftButtonDownのイベントを取り、ヒットテストを使ってどのモデルがクリックされたのかを判断する処理を独自に実装する必要がありました。

川西 裕幸のブログ : HitTest3D



.NET Framework 3.5で追加されたContainerUIElement3DとModelUIElement3Dは、3Dオブジェクトのモデルにおけるイベントを提供するクラスです。
実際にContainerUIElement3DとModelUIElement3Dを使ったサンプルのコードは、下記のようになります。


XAML

<Window
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   x:Class="Window1"
   Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <Model3DGroup x:Key="model3d">
            <GeometryModel3D>
                <GeometryModel3D.Geometry>
                    <MeshGeometry3D TriangleIndices="0,1,2 3,4,5" Positions="-1,-1,2 1,-1,2 1,1,2 1,1,2 -1,1,2 -1,-1,2 "
        TextureCoordinates="0,1 1,1 1,0 1,0, 0,0 0,1"/>
                </GeometryModel3D.Geometry>
                <GeometryModel3D.Material>
                    <DiffuseMaterial Brush="DarkOrange" />
                </GeometryModel3D.Material>
            </GeometryModel3D>
            <AmbientLight Color="#FFFFFFFF"/>
        </Model3DGroup>
    </Window.Resources>
    <DockPanel>
        <Viewport3D HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <Viewport3D.Camera>
                <PerspectiveCamera LookDirection="3,-3,-2" NearPlaneDistance="0.1" Position="-3,3,4" UpDirection="0.5,0.5,-0.5"/>
            </Viewport3D.Camera>
            <ContainerUIElement3D>
                <ModelUIElement3D MouseDown="ModelUIElement3D_MouseDown" Model="{StaticResource model3d}"/>
            </ContainerUIElement3D>
        </Viewport3D>
    </DockPanel>
</Window>


Visual Basic
Class Window1
 
    Private Sub ModelUIElement3D_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs)
        MsgBox("マウスがクリックされました。")
    End Sub
 
End Class


通常のイベントハンドラの記述と同じになりますので、ヒットテストを使った方法に比べると格段に楽になったと思います。WPFで3DをUIの一部に使っていた方にとっては、非常にありがたい機能追加ですね。