川西 裕幸のブログ

Windows Graphics & Presentaiton Technologies for Developers

WPF3.5の新機能④ UIElement3D その2

WPF3.5の新機能④ UIElement3D その2

  • Comments 1

UIElement3D にはもうひとつ大きな利点があります。UIElement3DにはOnModelUpdateとInvalidateModelメソッドがあり、これによりデータバインディングを使ったモデルの修正が可能になりました。

これまで、WPF 3D の限界に挑戦するとき、新しい ModelVisual3D  を作成して、古いものと入れ替えるという戦略をとってきました。これは描画中の ModelVisual3D を修正する手段がなかったからです。しかし、UIElement3D を使えば描画中のモデルを修正できるので、このような入れ替えは必要なくなりました。UIElement3D は、以前紹介したWPFでの環境マッピングやモーフィングなどにも適用できるはずです。SDK の中に UIElement3D Sphere のサンプルがありますので参照してください。

例えば、スキニングを行うとき WPF 3.0 ではスライダのコールバックを次のように記述していました。

private void SliderMoved(object sender, RoutedEventArgs e)

{

    myScene.Children.Clear();

     ModelVisual3D myMV3D = new ModelVisual3D();

     myMV3D.Content =

       (Model3D)CreateModel3D(mySlider.Value, 0.0);

    myScene.Children.Add(myMV3D);

 }

 

しかし、WPF 3.5 ではCylinderクラスを作成し、そこに一方の角度を表わすAngle依存プロパティを設定し、スライダの値をAngleにデータバインディングさせれば、このようなコールバックを作成する必要がありません。Windows1.xaml.cs にはなにも追加せずに、Cylinderクラスを利用することができます。よりオブジェクト指向的なプログラミングができるようになったと言ってしまえばそれまでですが...

 

XAML の記述

<Slider Width=300 Maximum=60 

      Minimum=-60Margin=10

 Value={Binding ElementName=MyCylinder, Path=Angle}/>

<Viewport3D Width=480 Height=400 Margin=10 >

 <Viewport3D.Camera>

  <PerspectiveCamera Position=0,3,10 FieldOfView=45/>

 </Viewport3D.Camera>

 <local:Cylinder x:Name=MyCylinder  />

 <ModelVisual3D>

  <ModelVisual3D.Content>

   <DirectionalLight Color=White Direction=0,0,-1/>

  </ModelVisual3D.Content>

 </ModelVisual3D>

</Viewport3D>

 

Cylinderクラス の記述

protected override void OnUpdateModel()

{

  GeometryModel3D model = new GeometryModel3D();

  model.Geometry = Tessellate(Angle);

  model.Material = new DiffuseMaterial(Brushes.Blue);

   Model = model;

}

 

public static readonly DependencyProperty AngleProperty =

  DependencyProperty.Register("Angle",

  typeof(double),   typeof(Cylinder),

  new PropertyMetadata(0.0, AnglePropertyChanged));

 

private static void AnglePropertyChanged(

  DependencyObject d, DependencyPropertyChangedEventArgs e)

{

  Cylinder s = (Cylinder)d;

  s.InvalidateModel();

}

 

public double Angle

{

  get { return (double)GetValue(AngleProperty);}

  set {SetValue(AngleProperty, value);}

}

 

Leave a Comment
  • Please add 7 and 6 and type the answer here:
  • Post