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

Popfly Game Creator を触ってみた

TechCollab2008-06-01


最近は色々と手を出してサーベイしているためネタが溜り気味になってしまっている。しかも、書きやすい難易度の低いものからアウトプットしているため、なかなか本当に書きたいことが後回しになっているという状態。ということは自覚しているものの、今日はその難易度の低め(?)のPopfly Game Creatorについて今更ながら書いてみようと思う。

Popfly Game Creator とはPopflyプラットフォーム上でSilverlightゲームコンテンツを容易に作るためのツールである。一ヶ月前くらい(2008年5月)に発表されたのだが、あまり魅力的に思わなかったため今まで放置していたのだが、触ってみるとこれが実によく出来ている。という訳でここでゲームを作る手順とカスタマイズについて簡単に書いてみる。

Make Game

様々なテンプレートが用意されているが、ここではスクラッチから作ってみる。

  • ゲームに使うアバタを選択

今回は簡単なシューティングゲームを作ってみるため、操作するアバタとして「ワニ」を、敵として「エイリアン」(?)、また弾や弾が当たったときの爆発アクションなどを選択する。

  • シーンを決定しアバタを配置する

ゲームの背景を選択し、適当な位置にアバタを配置する。

  • アバタの挙動を決定する

ここで、各アバタの動作や、アバタ同士のアクションについてを設定していく。キーボード、マウスイベントに応じたアバタアクションなどもここで行う。ここでは、アニメーションの微妙な設定など様々なことができる。

また、各イベントを受けてのアバタの挙動についてはJavaScriptで記述することが可能で、自由にカスタマイズすることができる。

さらに、アバタ自体のカスタマイズも可能で、アバタを定義しているXAMLを編集することにより行う。この編集はExpression Blendなどを利用しつつ行う。

かなり省略した説明となったが、詳しい説明はこちらの動画を参照。これを見れば基本的なゲームのつくり方については理解できるものと思う。ゲームのカスタマイズについては、裏で動作しているだろうSilverlightのコードをイメージしつつ実装していけば*1、色々といじくれると思う。

Deploy Game

出来たゲームは様々な形で公開することが可能。やはりPopflyに関心するのはこのDeployの幅広さ。Facebookアプリとして、またはVistaガジェットとして、標準で様々なDeploy手段が容易されている。ということで、上の手順を経て出来たゲーム(?)はこちら(上下キー:ワニ移動 スペース:火を噴く)。
http://www.popfly.com/users/TechCollab/Crocodile%20Shooting.small

参考

普通にゲームを作りたい人は下にあるようなGame Creatorのビデオを参照し、本格的にカスタマイズしたい方は、Actirs、Scenes、Gameなどの各コンポーネントの実装コードを参照し理解したらよいのではないかと思う。

感想

そんな感じでGame Creatorを軽く触ってみたが、SilverlightをベースとしてマッシュアッププラットフォームPopflyはどんどんと進化しているようだ。しかし、いかんせんその使いどころのイメージが一年経った今でもいまだにわかない。マッシュアップを体験できる、ゲームを簡単に作れる、というお遊び感覚では魅力だが、Popflyを使って自分のサービスを開発していきたいか、となると話は別。Popflyはそういうサービスを作ることには向いていないし*2、そもそも目標とはしていないのかもしれない。また、Popflyは初心者にとっては随分楽と思う一方で、ギークが触れることはないんだろうな、と思う*3。となると、初心者(例えばPCをさわりはじめた子供)がマッシュアップすごい!といってPopflyを使うかといえばそうではないと思う。Popfly、魅力的なサービスだと思うが今後の進む方向については慎重に見ていきたい。

今日の一枚

今日の写真は知り合いからもらったStarbuck City Magのソウルバージョン。海外に行く方は是非お土産にどうぞ。

おまけ

これを書いた直後あたりにGoogle Gears Location APIというものを知った。これは興味深い。
Google Code Archive - Long-term storage for Google Code Project Hosting.

*1:これが結構肝だと思う。

*2:向いてないということは無いが、自分のサービスを作ろうという人がPopflyを使おう、という機会はめったにないと思う。

*3:自分の直感的にそう思う。

Deep Zoom Composer 出力ファイルフォーマットを考える

TechCollab2008-05-28


今更ではあるが今日はDeepZoom関連のネタを書いてみようと思う。Silverlight 2では新しくMultiScaleImage Classが追加され、ある処理を施された画像データインタラクティブに操作することができる(具体的な実装についてはhttp://blogs.msdn.com/mohno/archive/2008/03/12/silverlight-2-deep-zoom.aspxなどで紹介されているため省略)。
Deep Zoom の簡単なデモ
しかし、このある処理が施されたということに一癖あって、MultiScaleImageを利用する際には、事前にDeep Zoom Composerで画像の処理をおこない、そこで出力されたデータをSource Propertyに指定するということになっている。

<MultiScaleImage Source="DeepZoomData/info.bin" 
      ViewportWidth="1.0" Width="300" Height="300">
</MultiScaleImage>

このようにMultiScaleImageという一見何か汎用的なことが出来そうな感じのするクラスだがいかんせん限定的なものとなってしまっている。これは他の方々も思っていることであるようだ(下はFirst Look: Silverlight 2.0 UI Controls: ASP Allianceからの引用)。

The MultiScaleImage control is perhaps the worst named control in the current Silverlight 2 UI controls collection. The control is really the required front-end tool for taking advantage of Silverlight's new Deep Zoom technology (formerly Sea Dragon in MS Labs). Deep Zoom enables you to display HUGE images on the web in a ZUI (zoomable user interface) with smooth, animated transitions that give the illusion of seamless image zooming.

じゃあ、Deep Zoop Composerの出力するファイルフォーマット(ex. info.bin)って具体的にどうなっているのだろう、ということを考えてみたところ、色々と調べている方がいた。またここらの話題は各種フォーラムでも話題になっているようだ。そもそも、Deep Zoom Composerに同梱されているSparseImageTool.exeやImageTool.exeを利用してコマンドラインからDeep Zoomファイルを出力することができる。ここではそこらを使いつつうまく解析をしている模様。
Project Silverlight: Deep Zoom items.bin file decoded

彼のフォーマット予想は次の通り。

Bytes (Hex)
00 Version (2)
01-04 UseStringsFile (0)
05-08 MinLevel (0)
09-0C MaxLevel (8)
0D-10 PageSizeLog2 (8)
11-14 ?? - PageQuality? (1)
15-1C ?? - PageFormat? (jpg)
1D-20 NextItemId (6)
21-24 ItemCount (6)
Thumbnail information for 1 thumbnail (Repeat for each thumbnail)
25-28 Thumbnail Id (0)
29-2C MinLevel (0)
2D-30 MaxLevel (8)
31-34 SizeX (0.6953125)
35-38 SizeY (0.521484375)
Item information (Repeat for each item)
9D-A0 Item Id (0)
A0-A4 Init Length (24)
A4-BC Init (test2_images\DSCF0067.sdi)
BD Relative (1)
BE-C1 Type Length (16)
C2-D1 Type (ImagePixelSource)
D2-D5 Thumb (0)

実際に出力されたファイルを見てみてもそのような感じになっているようだ(ちゃんとは見てないが。。。)。

まだBetaの段階なのでなんともいえないが、フォーマット仕様の公開とMultiScaleImageの汎用的な用途が示されればここらはもうちょっとありがたみのあるものになると思う。

今日の本

キャズム

キャズム

ハイテク分野に限らずマーケティング本としてかなりお気に入りの本。

Silverlightでfullscreen & resize

TechCollab2008-05-14


今日はSilverlightでのfullscreenとresizeの実装について整理してみようと思う。WPFではViewboxという便利なレイアウトクラスがあるがSilverlightにはないので独自に実装しなくてはならない。ということで、Silverlight 1.0とSilverlight 2.0 betaのそれぞれの実装についてまとめる。基本的にViewboxの機能を持たせるためにウィンドウのリサイズ、フルスクリーンイベントを受けてCanvasのscaleとtranslateを変更させているだけ。コードはコールバックのロジックのみを載せる。サンプルのソースはこちら


Silverlight 2.0 beta

http://viralfeed.net/sample/fullscreen2/

C#による実装。

    public partial class Page : UserControl
    {
        private double _originalWidth;
        private double _originalHeight;

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

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            _originalWidth = rootCanvas.Width;
            _originalHeight = rootCanvas.Height;

            Resize();
            Application.Current.Host.Content.Resized += new EventHandler(Content_Resized);
        }

        void Content_Resized(object sender, EventArgs e)
        {
            Resize();
        }

        private void FullScreenButton_Click(object sender, RoutedEventArgs e)
        {
            Content content = Application.Current.Host.Content;
            content.IsFullScreen = !content.IsFullScreen;
            Resize();
        }

        private void ImageMenu_MouseEnter(object sender, MouseEventArgs e)
        {
            Image img = (Image)sender;
            string sbName = img.Name + "ZoomIn";

            Storyboard anim = FindName(sbName) as Storyboard;
            anim.Begin();
        }

        private void ImageMenu_MouseLeave(object sender, MouseEventArgs e)
        {
            Image img = (Image)sender;
            string sbName = img.Name + "ZoomOut";

            Storyboard anim = FindName(sbName) as Storyboard;
            anim.Begin();
        }

        private void Resize()
        {
            double currentWidth = Application.Current.Host.Content.ActualWidth;
            double currentHeight = Application.Current.Host.Content.ActualHeight;

            double uniformScaleAmount = Math.Min((currentWidth / _originalWidth), (currentHeight / _originalHeight));
            rootScaleTransform.ScaleX = uniformScaleAmount;
            rootScaleTransform.ScaleY = uniformScaleAmount;

            double scaledWidth = Math.Min(_originalWidth * uniformScaleAmount, currentWidth);
            rootTranslateTransform.X = (Math.Min(rootCanvas.ActualWidth, currentWidth) - scaledWidth) / 2d;
        }
    }
Silverlight 1.0

http://viralfeed.net/sample/fullscreen1/

JavaScriptによる実装。

var _originalWidth;
var _originalHeight;
var slPlugin;

function onLoaded(sender, args)
{   
    slPlugin = sender.getHost(); 
    var rootCanvas = slPlugin.content.FindName("rootCanvas");
    
    _originalWidth = rootCanvas.Width;
    _originalHeight = rootCanvas.Height;   

    slPlugin.content.onResize = onResized;     
    Resize();    
   
}

function toggle_fullScreen(sender, args)
{    
    slPlugin.content.fullScreen = !slPlugin.content.fullScreen;     
    Resize();        
}

function onResized(sender, eventArgs)
{
    Resize();
}

function Resize()
{
    var rootScaleTransform     = slPlugin.content.FindName("rootScaleTransform");
    var rootTranslateTransform = slPlugin.content.FindName("rootTranslateTransform");   
    var rootCanvas             = slPlugin.content.FindName("rootCanvas");
        
    var currentWidth  = slPlugin.content.actualWidth;
    var currentHeight = slPlugin.content.actualHeight;   
    
    var uniformScalceAmount   = Math.min((currentWidth/_originalWidth),(currentHeight/_originalHeight));
    rootScaleTransform.ScaleX = uniformScalceAmount;
    rootScaleTransform.ScaleY = uniformScalceAmount;
    
    var scaledWidth = Math.min(_originalWidth * uniformScalceAmount, currentWidth);
    rootTranslateTransform.X = (Math.Min(rootCanvas.ActualWidth, currentWidth) - scaledWidth) / 45;
}

function ImageMenu_MouseEnter(sender, args)
{
    var TargetId = sender.Name + "ZoomIn";
    var ImageMenuEnterAnimation = sender.findName(TargetId);
    ImageMenuEnterAnimation.begin(); 
}

function ImageMenu_MouseLeave(sender, args)
{
    var TargetId = sender.Name + "ZoomOut";
    var ImageMenuLeaveAnimation = sender.findName(TargetId);
    ImageMenuLeaveAnimation.begin(); 
}
注意事項

当然のことながら配置する際にはxamlとxapのMIME設定を忘れずに。
xap: application/x-silverlight-app
xaml: application/xaml+xml

今日の写真

会社同僚の方の結婚式二次会の様子。二次会の写真は近いうちにSousuke Hirayama | Flickrにupする予定 > to 関係者のみなさま。
http://www.orioria.jp/

Starbucks City Mug - Dailian -

TechCollab2008-04-10


会社の先輩から大連土産としてStarbucks City Mugをもらったということで自慢げに写真をUP。意外にCity Mugって知らない人多いことにびっくり。皆さんも海外に出かけるときはお土産に是非!上海で買う時間が無かったのが悔やまれる。

Human Computer Interaction in the year 2020

via yhassy's twitter post
Human Experience and Design: Microsoft Research
つい先日Surfaceが製品としてAT&Tストアにお目見えするというニュースもありましたが、ここでは2020年にはHuman Computer Interactionがどうなる?という議論をまとめられています。なかなか若干まだ夢のようなお話もあるが、わくわくさせられるものが多くあるので一読されてはいかがでしょうか。最近はソフトウェアサービスの視点は常にWEBオンリーで語られる傾向がありますが、このようにデバイスと連携した実世界と関わるソフトウェアというとも魅力たっぷりです。

Book Review: 次世代の広告を考える

Viral Feedを立ち上げようと動いていたこともあり、最近は広告というものにとても興味があるのですが、その勉強がてら最近2冊の本を購入。2007年の本なので若干古い話もありますが、なかなか興味深く読むことができました。やはり広告は効果評価までを面倒みないとビジネスストーリーとして成立しないし、Viral Feedではここらへんの観点に乏しかったと反省しています。とはいっても、モバイルを意識した「位置依存の情報注入と近隣デバイスへの伝播」というテーマについては魅力を感じるということで引き続き考えていきたい。
Viral Feedはついつい広告モデルについての議論が多くなってしまったが、本当に実現したかったのは次のようなこと。これはいつぞやかに酔った勢いで書き込んだ自分のtwitter post。

「一期一会の関係なのに情報をやり取りできないのは不幸せ。ある時ある場所で出会った人の持つ情報を得ることができたならば幸せ。」

次世代広告コミュニケーション

次世代広告コミュニケーション

次世代広告テクノロジー

次世代広告テクノロジー

おまけ

現在発売中のSoftware Design 4月号に未踏関連の記事で私の写真が載っているようですので興味のある方(そんな人はいないと思うが;)はぜひ一読を!

そういえば最近技術ネタをめっきり書かなくなってしまった。。。しかも、定期的に書かなくなったから日本語能力が落ちてきている。

Mobile 2.0

TechCollab2008-04-03


さて、もう早いものですっかり春ですね。ということで3月で充電したパワーを使ってそろそろ新しいステップに進んでいこうと思います。その一貫としてEnglish Blogを始めます。いい加減これ以上のレベルに進むならば言語の壁をさっさと取り除きたいのです。

The Challenge of Innovation (準備中): http://shirayama.blogspot.com/

Mobile 2.0

なかなか興味深いスライド(後日これについてのコメントは追加する予定)。

Windows Mobile 6.1 and 7

つい最近Windows Mobile 6.1の発表がされましたが、WMもどんどんと進化しているようですね。WM5/6では実際に使っているとやはりまだまだ使い勝手が悪くてずっと使い続けたいという思いはないですが、6.1と7と進化しUIが向上しうまくMesh構想*1と絡めたサービスが出てくればとても魅力的なデバイスになのではないでしょうか。

  1. Windows Mobile 6.1

  1. Windows Mobile 7 (futures...?)

» Exclusive: Windows Mobile 7 To Focus On Touch and Motion Gestures » InsideMicrosoft-part of the Blog News Channel

Book Review

通勤中の読書ははかどるので2日に1冊は何かしらの本を読んでいる気がします。ということで最近読んだ本をご紹介。

おまけ

銀座に桜が咲いていたのでついつい写真を撮ってみましたw

Book Review

TechCollab2008-03-19


さてさて、相変わらずのご無沙汰のエントリです。最近は未踏もひと段落して、今まで会えなかった友人とあったり、色んなところに出かけたり、本を読んだり、と有意義な日々を過ごしてました。
そんなことを考えながら、部屋の隅をふと見てみると積み重なった本ががっつりと。。。ということで、今回はここ1ヶ月の間に読んだ本を書評もどきのコメントと合わせて振り返っていこうと思います。

とはいっても、明日の上海発の飛行機の時間を考えると、とっとと書いて早く寝たいところ;

新版MBAマーケティング

新版MBAマーケティング

まあ、マーケティングの定番書といわれる本。特に目新しいことが書いてある訳でもなく基本に忠実なマーケティングの教科書という位置づけ。知識として整理するのにはよい本だとは思うが、やはり事例を学んだり、実践として経験することが凄腕マーケッターへの道なのではないかと。

パラダイス鎖国 忘れられた大国・日本 (アスキー新書 54)

パラダイス鎖国 忘れられた大国・日本 (アスキー新書 54)

国内に閉じこもってしまった現状の日本を「パラダイス鎖国」と称し、その中で緩やかな開国を目指すべきではということを提起した本。とてもすんなりと引き込まれてとても面白く読めました。「プチ変人」が多く集まるシリコンバレーには近いうちにぜひ行きたい!

何か今の日本の閉塞感にもやもやとしている若者ってたくさんいると思う。自分のまわりにもたくさんいるし、自分もまさにそういう人間のひとり。その中で大事なのは、その閉塞感を打破していこう!俺が打破してやるぜ!という意気込みとハングリー精神のみ。

ウェブ時代 5つの定理―この言葉が未来を切り開く!

ウェブ時代 5つの定理―この言葉が未来を切り開く!

梅田さんの本は基本的にすべて読んでいるが、自分はこの本が一番のお気に入り。第一線で活躍、もまれている人々の魂のこもった言葉に触れることができるのは至福の喜び。

モバイル・マーケティング最前線 (BOOKMARK 001)

モバイル・マーケティング最前線 (BOOKMARK 001)

モバイルマーケティングの現状をまとめたムック本。現状を知る上ではよくまとまっていてわかりやすいと思う。

Silverlight 1.0 (Wrox Programmer to Programmer)

Silverlight 1.0 (Wrox Programmer to Programmer)

Silverlightのまとまった本というのはなかなかないが、この本はよくまとまっていると思う。まあ、とはいえSilverlight2.0 betaをいじくれる現状だとこの本の魅力はちょっと下がってしまう。あ、そろそろSilverlight2.0の情報もアウトプットしていきたいものです。

ザ・マインドマップ

ザ・マインドマップ

マインドマップ本。特に感想はなし。マインドマップは使いどころによってはとても効力を発揮すると思うが、常にマインドマップで整理しよう、というスタンスだと自分の中ではうまくいかない。使いどころが大事かと。

文章的に読みづらいところもあり、かつwebに対する考察がやはり乏しい、という部分が気になったが、広告会社の現状というものがよくわかり色々と考えさせられた。広告インフラって色々と改善の余地がまだまだあると思う!

ASP.NET AJAX in Action

ASP.NET AJAX in Action

ASP.NET Ajaxの本。ASP.NET Ajaxの書籍は国内でも色々出されていますが、これがベストだと思います。ぜひ一読を!

エッセンシャルWPF:Windows Presentation Foundation (Programmer's SELECTION)

エッセンシャルWPF:Windows Presentation Foundation (Programmer's SELECTION)

まあ、特に感想なしです。WPFはもうずいぶん昔の技術という感じが個人的にはしていますが、まだまだ普及はしていないですね。WPFは一度使えば開発生産性、リッチな表現に病み付きになってしまうのですが、その一歩の啓蒙がまだうまくいっていないようです。

.NET&Windowsプログラマのためのデバッグテクニック徹底解説 (マイクロソフト公式解説書)

.NET&Windowsプログラマのためのデバッグテクニック徹底解説 (マイクロソフト公式解説書)

前から欲しかった本だったので、奮発して購入。Winアプリの開発に携わっている人間ならばぜひとも1冊手元において活用すべし!