Silverlightで3D - Kit3D a 3D C# graphics engine for Microsoft Silverlight - を使ってみた

今日も一ヶ月くらい時代をさかのぼったSilverlightネタ。SilverlightではWPFのような3D(Viewport3D)サポートがされていないため、3Dのコンテンツを表現するには、ここにあるような2D-3D座標変換を計算しうまく投影させなくてはならない。
最近ではそのような面倒なことをやってくれるライブラリが色々と出てきたようだが、やはり一番目を引くのはやはりKit3D。このライブラリでは、ほぼWPFの実装方式を踏襲しているためにWPFで作ったものをそのまま移行するということも簡単にできる。
CodePlex Archive

ということで、Kit3Dを利用し作ってみたサンプルはこちら。3Dということで定番なティーポットを回転させる単純なサンプルを作ってみた。
http://viralfeed.net/sample/silverlight3d/

基本的な実装は下記の通り。

...
using Kit3D.Windows.Controls;
using Kit3D.Windows.Media;
using Kit3D.Windows.Media.Media3D;

namespace Silverlight3d
{
    public partial class Page : UserControl
    {
        private ModelVisual3D modvis;
        private Viewport3D viewport;

        public Page()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Page_Loaded);
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            TeapotShow();

            Storyboard s = this.FindName("AnimationLoop") as Storyboard;
            s.Begin();
        }

        double rotation = 0;
        private void AnimationLoop_Completed(object sender, EventArgs e)
        {
            if (modvis != null)
            {
                Transform3DGroup tg = new Transform3DGroup();

                tg.Children.Add(new RotateTransform3D(
                                    new AxisAngleRotation3D(
                                        new Vector3D(0, 10, 0),
                                        rotation),
                                        new Point3D(0, 0, 0)));
                modvis.Transform = tg;
            }

            rotation += 3;

            ((Storyboard)sender).Begin();
        }

        public void TeapotShow()
        {
            viewport = new Viewport3D();
            viewport.HorizontalAlignment = HorizontalAlignment.Stretch;
            viewport.VerticalAlignment = VerticalAlignment.Stretch;
            CompositionTarget.FrameRate = 15;

            TeapotMesh tm = new TeapotMesh();
            MeshGeometry3D mesh = tm.Geometry;

            GeometryModel3D geomod = new GeometryModel3D();
            geomod.Geometry = mesh;
            geomod.Material = new DiffuseMaterial(new Kit3DBrush(new SolidColorBrush(Colors.Blue)));
                
            //geomod.SeamSmoothing = -1;

            modvis = new ModelVisual3D();
            modvis.Content = geomod;
            viewport.Children.Add(modvis);

            PerspectiveCamera cam = new PerspectiveCamera(new Point3D(0, 0, 8),
                                                          new Vector3D(0, 0, -1),
                                                          new Vector3D(0, 1, 0),
                                                          45);
            viewport.Camera = cam;

           
            this.LayoutRoot.Children.Add(viewport);
        }
    }
}

性能の面やその他機能不足など少々不満な点もあるが、やはりWPFと同じ実装モデルが利用できることは大きな利点だと思う。川西さんのブログではHitTestはないとあるが、ぱっとみたところ実装はされている模様。画像をテクスチャとして動的に張った3D Cubeのサンプルなどもあるようだ。
http://sildev.net/3DCubes/index.html