16 September 2009
ページ ツール |
すべて
Flash/ActionScript開発のためのオープンソースコミュニティ「Spark project」では、毎月勉強会を開催しています。スキルレベルや立場にとらわれず、Flash好きが集まり、FlashやActionScript に関するトピックについて勉強する、フランクなイベントです。
今年5月末に開催された第9回勉強会には、ちょうど来日していたSWFObjectの制作者Geoff Stearnsさんも参加されました。SWFObjectとは、HTML内にSWFを埋め込むためのライブラリです。SWFObjectを使えば、Flash Playerのバージョン検出機能や代替コンテンツ提供機能などを手軽に実装でき、海外ではデファクトスタンダードと言えるくらい多くのFlasherが利用しています。読者の中にも、使っているという方は多いでしょう。実は、Dreamweaver CS4でもSWFの埋め込み手法として採用されています。
勉強会では、Geoffさんとのトークセッションが行われましたが、その日はもう一つスペシャルイベントがありました。なんと、勉強会の2日前がGeoffさんの誕生日。そこで、急遽、有志のFlasherによる「Happy Birthday 大喜利」が企画されました。Flasherならではの趣向を凝らしたお祝いでした。SWFObjectの解説は上記リンクに譲るとして、本記事では大喜利で披露された「FlashユーザーによるFlashユーザーのための誕生日プレゼント」について、制作者のみなさんに解説していただきましょう。
なお、第9回勉強会の模様はUstreamのアーカイブで見ることができます。ビデオ後半には、「Happy Birthday 大喜利」もあります。ビデオと一緒に、これ以降の記事を楽しんで下さい。
http://www.ustream.tv/recorded/1571316


上野賢一(Keno)
http://keno.serio.jp/
twitter ID:keno42
僕のアシスタントの「猫パティシエ」が登場して、Webカメラを通してGeoffさんの顔をよーく観察します。彼はしばらく考えたあと、おもむろにケーキのスポンジにチョコレートクリームとストロベリークリームを塗りたくります。だんだんと顔のように見えてきました。さっき見たGeoffさんの顔をクリームで描いてくれたのです。ケーキの縁をクリームでかざり、ロウソクを立て、誕生日ケーキが完成します。最後はロウソクを吹き消しましょう。誕生日おめでとう!!
Ustream経過時間(1:14:40)
このプログラムは、FlashDevelopのAS3プロジェクトとして作成しました。順を追って、制作工程を解説します。
STEP01 素材の準備
まずは猫パティシエの画像を準備します。自作のお絵描き掲示板を使用して、次の三枚の絵を描きました。

これらの画像の背景を切り抜き、Loaderでロードして使用しました。猫パティシエが顔を描くときの効果音や、最後の歓声などの音素材は市販のものを使用しています。音素材はwav形式だったので、Flashのタイムラインに音を貼り付けただけのものをパブリッシュし、そのSWFファイルをEmbedして使用しました。
STEP02 フルスクリーンのソース矩形指定
プレゼン時に使用したノートPCは性能があまりよくなかったので、フルスクリーン時の表示範囲を狭くとってFPSの維持を試みました。次のコードを使い、フルスクリーン時の描画元として画面左上320×240ピクセルの矩形領域を指定しています。
stage.fullScreenSourceRect = new Rectangle(0, 0, 320, 240);
STEP03 ケーキ本体の配置
真上から見るビューだとケーキに見えなさそうなので、立体的に配置しました。立体配置にはFlash Player 10の機能であるrotationX、rotationY、rotationZとzプロパティを利用して、四角を描画しただけのSpriteを用意し、角度を変えながら組み立てました。
STEP04 顔の撮影・加工
Webカメラを通して画像を取り込み、明度的に暗い部分と、HSV成分で肌色っぽい部分を抽出しました。暗い部分はチョコレート、肌色の部分はストロベリークリームという設定を説明しながら、猫パティシエの手が端から順番にケーキ上をなぞっていき、なぞった部分を先ほど抽出した画像とマスクを使って塗っていきます。
MEMO:
ミカン日記: ActionScript3.0で肌色検出
http://kaiho-16.seesaa.net/article/62520420.html
猫パティシエの手・ハケも、Flash Player 10の3D機能を利用して配置することで、奥行き方向への移動も自然に見えるようにしています。なぞる動作は、BetweenAS3を使用してアニメーションさせました。
STEP05 ロウソク配置
ロウソクはGeoffさんの年齢を聞いてから本数を決定し、顔部分の邪魔にならないようにクリックで配置していきました。ロウソクの先端には、TeraFireを配置して、ゆらぐ炎を演出しています。
吹き消すボタンを押してもらったら、炎用のTeraFireを傾けて消し、再度TeraFireを煙用の設定で配置します。同じTeraFireクラスですが、設定次第で炎のようにも煙のようにも見せることができます。
炎のTeraFire: new TeraFire(0, 0, 10, 30, 0xFFFF00, 0xFF0000)
煙のTeraFire: new TeraFire(0, 0, 2, 200, 0xAAAAAA, 0xBBBBBB)


イズカワタカノブ氏
http://izukawa.org/
SWFObjectをメンテナしている方の誕生日ってことで、何かしらの形でSWFObjectを取り入れた形にしたいとは思っていました。で、パッと思いついたのが、普段お世話になっているSWFObjectに対してのありがとうの気持ちを込めて、SWFObjectを使って「Happy Birthday」を伝えたら素敵なんじゃないかなーって。それをまるっと形にしてみました。
SWFObjectのソースコードの文字列から、Happy Birthdayの一文字づつを探していって、全部見つけることができたらまとめて表示するっていう、そこそこありがちなネタです。最初の「H」が見つかるまでが異常に遅かったり、その後も至ってスローペースな展開だったりと、見ていただければ分かるとおりグタグダです。特筆すべきは、口頭で「この流れてる文字は、swfobject.jsのソースコードなんだよ」って教えてあげないと、大半の人は気付かない点でしょうか。
Ustream経過時間(1:19:50) wonderflでも公開中
最終的にwonderflにアップしようと思っていたので、使用するデータやライブラリなど、環境はwonderflに合わせて作りました。読み込むswfobject.jsのデータに関しては、 Google Codeにあるswfobject.jsはセキュリティポリシーの関係でFlashからダイレクトに読み込むことができなかったため、Google AJAX Liraries APIに上がっている swfobject.jsを使っています(こちらは、Flashからダイレクトにアクセス可能)。
ライブラリや実装方法に関しては、特にトリッキーなことはしてはいませんが、個人的に実験的だったのはBetweenAS3でしょうか。まだまだ制作途中とのことですが、ベンチマークテストではピカイチな成果を叩き出していたので、今回のようなオブジェクトを動かし続ける環境でも、あまりパフォーマンスを気にせずに使用することができました。
他にもPapervision3Dも使用しているので、結構パフォーマンスは気になっていたのですが、動かしてみると、モタつきなどが気にならなかったのはさすがだと思いました。BetweenAS3は、今も活発に開発が進んでいるので、これから先の発展にも期待できると思います。
根幹部分には、ActionScript Thread Library(以下そうめん)を使いました。普段から使い慣れているということもあるのですが、作りながら考えるといった場面では、ロジックの入れ替えが容易なそうめんは今回も大活躍でした。


加茂雄亮氏
http://log.xingxx.com/
Flasherなら誰しもが一度は触ったことがあるタイムライン。最近はActionScriptばかり書いて(Sparkに来ている人たちは特にね!)、タイムラインを触る機会がないかも知れません(Geoffさんも最後に触ったのは2年前だとか…)。Flash CS4が、ただのコンパイラになってはいませんか? でも、よく考えてみてください。Flashって、アニメーションツールですよね。ActionScriptが「アクション」という名前で、おまけ程度だったアニメーション全盛期。みんさんは、フレームを増やして、トゥイーンを付けて…アニメーションを作っていたはずです。もちろん、Geoffさんも。タイムラインは、僕らFlasherの原点なんですよね。
そんな、昔を思い出す感覚で、タイムラインを使って誕生日メッセージをこしらえてみました。もちろん、Flash CS4だって立派なアニメーションツールです。IK(インバースキネマティクス)だって簡単にできちゃうほど、進化しました。最近タイムラインいじってないなっていう方は、この機会に触ってみましょう。
Ustream経過時間(1:24:06)
タイムラインに文字を表示させる。一見、大変な作業に思えるかもしれませんが、実は全自動です。手打ちはしません。手打ちなんてしていたら日が暮れてしまいますからね。ではどうするかというと、JSFLとSWFPanelを使用します。これらはFlash CS4のオーサリングを効率化させるための拡張機能の一つです。JSFLは「Flash Javascript API」と呼ばれるもので、Flashのオーサリング機能をJavascriptのAPIで実行できます。SWFPanelは、Flash CS4に独自のパネルを実装するための仕組みで、SWFで動作します。ただのSWFですから、ActionScript 2.0でも3.0でも開発できます。
今回のポイントは、SWFPanelとJSFLの連携です。相互が得意とするところをうまく使い、互いの弱点を補い合います。つまり、JSFLにはオーサリングに注力させて、表現の部分でActionScriptを使用するわけです。
まず、文字をTextFieldで出力後、文字の幅高をMMExecute関数を使ってAS3からJSFLに渡します。ここでは、MMExecuteの使い勝手が多少悪いので、拡張したMMExecute2を使っています。JSFLは、幅の値をフレーム数(1px = 1フレーム)、高さの値をレイヤー数として(1px = 1レイヤー)、レイヤーとフレームをタイムラインに追加します。
ActionScriptに戻り、BitmapDataにTextFieldの文字を描画します。次にBitmapDataのgeVecotorで取得したピクセルデータを走査して黒(0x000000)であれば、そこには色があるとして、配列のポインタから座標を割り出し、JSFLに送ります。
最後にJSFLは、_yをレイヤー番号、_xをフレーム番号として、該当の箇所にあるフレームをモーショントゥイーンに変換すれば、タイムラインのフレームでできた文字ができあがります。
以下は、TextFieldの描画情報をBitmapDataに書き込み、走査して把握したxとyの値をJSFLの関数に渡すコードです。
var tf:TextField = new TextField();
tf.text = "message";
MMExecute2.setDefault(MMExecute2.CONFIG_JS_URI,"VisualizeTimeLine")
MMExecute2.run("init", [Math.round(tf.height), Math.round(tf.width)]);
var canvas:BitmapData = new BitmapData(tf.width, tf.height, false);
canvas.draw(tf);
drawVector(canvas);
function drawVector(canvas:BitmapData):void {
var bytes:Vector.<uint> = canvas.getVector(canvas.rect);
bytes.fixed = true;
canvas.lock();
var color:uint, i:int;
var _x:int;
var _y:int = -1;
for (i; i < bytes.length; i++) {
color = bytes[i];
_x = i %canvas.width;
_y += !_x ? 1: 0;
if (!color) {
MMExecute2.run("setMotionTween",[_y,_x]);
}
}
}
詳しくは、「xingxx - JSFL :: Flashのタイムラインに文字を書く」を見て下さい。


大庭俊介氏
http://www.formes.jp
http://reinit.info/blog/
twitter ID : bao_bao
Geoffさんの誕生日に何をプレゼントしたらよいか、とても迷いました。小学生時代の誕生日会のワクワク感を思い出しながらアイデアを探しました。で、その結論、誕生日会で最も重要なのは「ハッピーな空気のシェア」であること。単純に会場を賑わすことが一番のプレゼントだと思い、FLARToolkitで作ったケーキを用意しました。
一見あたかもケーキが入っていそうなリボンが結ばれた白い箱。その側には、Webカメラとパソコンが。会場を賑わす、ただそれだけのために生まれてきた、食べられもしない、触ることもできない、そっと近づくと消えてなくなるケーキです(だって、マーカーに被るから)。
なお、プレゼンをする間の「私のテンパっていた挙動」「Webカメラのエラー」など、すべて演出のための計算であるとご理解いただきたいです。ホントです。
Ustream経過時間(1:29:30) Viemoでも公開中
bARthday cakeを制作する上で、大きく2つの作業をしています。
【Lightwave3Dでケーキをモデリング+アニメーション】
パソコンのスイッチをつける前に、大事な作業があります。
ケーキのことを理解できたところでモデリングの準備は、完了です。
ケーキ本体のモデリングをします。心がけることは、ポイント数を極力少なくすることと、三角ポリゴンで制作することくらいです。下図は、マッピングする前の状態です。

モデリングは、ある程度形が見えたら、いったん終了です。なぜなら、細かくモデリングしても、それがモニタ上で表現されるかどうかは分からないためです。マッピング作業をした後にイメージ通りにいかない場合は、ポイントを増やして、作りこんだりします。
次にマッピング作業に移ります。マッピングは、低ポリゴン制作においてはかなり重要なファクターです。以下のようなUVマップを作りました。




これらのUVマップをケーキ本体に貼ると以下のようになります。

これでケーキ本体のモデリングは終了です。次にロウソクの炎と煙をモデリングします。ここで気をつけるのは、アニメーションさせる部分に多めにポイントを打つことくらいで、他は先ほどのケーキ本体のモデリング作業となんら変わりません。
ロウソクのモデリングです。

モデリングが終了したら、炎と煙それぞれに、ボーンを仕込んでいきます。オレンジ色の部分は、各ボーンごとの稼動範囲を指定するウェイトです。ウェイトは、各ポイントごとに強さを設定できます。


煙も同様の作業をします。仕込み終わったら、モデリング作業は終了です。次にアニメーション作業に移ります。

タイムラインにキーフレームを打って、ボーンを動かして行きます。IK(インバースキネマティクス)を使う方法もあるのですが、この程度のポイント数と少ないフレーム数だと、ボーンを直接動かしてモーションをつけた方が、個人的には微調整が容易にできて作業が早いと思っています。

アニメーションをつけたら、Lightwave3Dでの作業は終了です。Papervision3Dでは、Colladaファイルを読み込むことができるので、Lightwave3DからCollada形式で書き出します。しかし、一筋縄ではいきません。この辺の詳しい内容は、noenoeさんの記事「LightwaveからColladaファイルを書き出すよ」を参考にさせていただききました。というより、催促して教えてもらいました。簡単に説明すると、以下の2つの工程を踏みます。
【FLARToolkit+Papervision3Dでケーキを表示】
Lightwave3Dから書き出したColladaファイルをPapervision3Dで読み込みます。Lightwave3DとFLARToolKitでは座標が変わってくるため、注意する必要があります。詳しくは、下記記事を参考にしてください(FLARToolKitはリビジョンによって、座標が違うようです)。
FLARToolkitで表示させます。事前に、仕込んであった合図でハッピーバースデーの歌をみんなで歌います。会場が賑わいます。これでbARthday cakeは完成です。
MEMO:
・FLARToolKit+Lightwave3Dの自分なりのまとめ
http://reinit.info/blog/?p=518
・簡単! FLARToolKitをはじめよう!
http://www.adobe.com/jp/devnet/flash/articles/flartoolkit.html

「今日は誕生日ということで、バースデーカードを作ってきました」 そう言って取り出された何やら見覚えのある図形が印刷してあるカード。はい、お察しの通りARです。カメラにマーカーを向けると…出てきたのは真っ白な四角形。あれあれ?…と思っている間にマーカーをぐるぐる回転させると、四角の中のパーティクルが動いて色が付き、「HAPPY BIRTHDAY」という文字がサンドアートのように浮かび上がる、そんな作品です。
Ustream経過時間(1:34:40) Viemoでも公開中
単にマーカーの上にモノが出てくるARはちょっと食傷気味なので、もっと遊び要素のあるものを作ろうと思ってできた作品です。この作品のポイントは、カードの傾きから、重力を求めるとこです。
private var _mat:Matrix3D = new Matrix3D();
private var _rot:Number3D = Number3D.ZERO;
private var _v:Number3D = new Number3D();
というプロパティをあらかじめ用意しておき、
_mat.copy(_baseNode.transform);
_mat.invert();
_rot = Matrix3D.matrix2euler(_mat, _rot);
_v.reset(0, 1, 0);
_v.rotateY(_rot.y);
_v.rotateX(_rot.x);
_v.rotateZ(_rot.z);
var gx:Number = -_v.x * 2.0;
var gy:Number = -_v.y * 2.0;
という感じの計算をすると、_baseNode(FLARToolKit によって提供される姿勢の変換行列) から二次元平面上の重力gxとgyが求まります。姿勢の変換行列の逆行列を求めることにより、マーカーに対する重力の傾きを求め、重力用に正規化したベクトルにその行列の回転だけを反映して、XとY成分(XとYにどれだけ傾いているか)を取り出しています。
ブログでは、マーカーとソース一式をアップしています。
http://www.be-interactive.org/?itemid=491
Spark projectの勉強会、そしてスペシャルイベントについての感想をGeoffさんに聞きました。
「驚きでしたね。勉強会にちょっと顔を出して、面白いプレゼンを見て、あとはみんなでビールを飲むってくらいに考えていたのに、彼らが“Geoffさんの誕生日祝いに作品を作ってきた”とプレゼンを始めたときは、すごくビックリしました。
間違いなく、素晴らしいバーケーションの思い出となりました。いや、人生の思い出と言ってもいいくらいです。ほとんど何も知らない遠い外国に行って、あのような歓待を受けるなんて、申し訳ないというか、本当に驚きました。
だから、プレゼンテーターの彼らには、“素晴らしい時間をありがとう”と大きな大きなサンキューを言いたいです。
もちろん、Spark project自体、素晴らしいプロジェクトですね。Flashエンジニアにとって必要なツールがすべて揃っているといってもいいでしょう。Spark projectのサイトは日本語がメインですが、言語の壁を越えて海外でも有名になりつつあります。非常に役立つツールが多く、ActionScriptを利用する世界中の人々に支持されるプロジェクトですね」
Geoff Stearns
YouTubeのFlashエンジニア。SWF埋め込み手法のデファクト・スタンダードとも言える「SWFObject」の制作者。YouTubeに入る以前には、Adobe、MTV、New York's MoMA、XM Radio、Comcast、Sony Pictures ClassicsなどのWebプロジェクトを手掛けている。また、ニューヨークのThe Cooper Unionにて教鞭を執り、フロントエンドのWeb開発を教えていた。
http://blog.deconcept.com/
(写真は、勉強会後の打ち上げにて。中心にいるのがGeoffさん)
