Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
WPF 3D の壁を破ろうシリーズ(?)第4弾です。でも今回は Direct3D などより WPF のほうが得意かもしれません。
Direct3D などでは 3D オブジェクトに張ってあるテクスチャの位置 (画像内のどの部分を表示するか) を移動させるにはテクスチャ座標を変更する必要があります。環境マッピングのとき紹介したように WPF 3D でテクスチャ座標を変更するにはジオメトリデータを書き直して描画しなおす必要があります。しかし WPF では Brush の Viewbox プロパティを使ってテクスチャの位置を決めることができます。このプロパティを変更するだけで、テクスチャの位置を変更できるので、ずっと簡単にテクスチャ移動アニメーションが実現できます。
マウスを押しながら移動すると、テクスチャがそれに合わせて移動するようなアニメーションを作ってみましょう。まず、次のように ModelVisual3D を定義します。
<ModelVisual3D x:Name="myModel1" >
<ModelVisual3D.Content>
<GeometryModel3D Geometry="{StaticResource mySubSphere}" >
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<DrawingBrush x:Name="mySphereBrush"
Viewbox="0, 0, 300, 300" ViewboxUnits="Absolute" >
<DrawingBrush.Drawing>
<ImageDrawing ImageSource="Media\AutumnLeaves.jpg"
Rect="0,0,1024,768" />
</DrawingBrush.Drawing>
</DrawingBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
コード側では次のようなコールバックを記述します。
private void OnMouseDown(object sender, RoutedEventArgs e)
{
isMouseDown = true;
oldPoint = Mouse.GetPosition((Window)sender);
}
private void OnMouseUp(object sender, RoutedEventArgs e)
{
isMouseDown = false;
currentPoint = new Point(mySphereBrush.Viewbox.X, mySphereBrush.Viewbox.Y);
}
private void OnMouseMove(object sender, RoutedEventArgs e)
{
if (isMouseDown)
{
Point newPoint = Mouse.GetPosition((Window)sender);
Rect r = new Rect(currentPoint.X - (newPoint.X - oldPoint.X),
currentPoint.Y - (newPoint.Y - oldPoint.Y), 300, 300);
mySphereBrush.Viewbox = r;
}
}
このテクニックはビデオにも適用できます。XAML の DrawingBrush の部分を次のような VisualBrush にするだけです。
<VisualBrush x:Name="mySphereBrush"
Viewbox="0, 0, 300, 300" ViewboxUnits="Absolute" >
<VisualBrush.Visual>
<MediaElement Source="Media/Bear.wmv" />
</VisualBrush.Visual>
</VisualBrush>
Comments
- Anonymous
July 16, 2011
myBlog: "IronPythonで、今度は ViewboxUnits を Absolute で Tile を実行する!" softgarden.blog.ocn.ne.jp/.../ironpython_view.html で、参考にさせて頂きました。
