<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
		xmlns:xhtml="http://www.w3.org/1999/xhtml"
>

<channel>
	<title>宇都宮ウエブ制作所 &#187; 正宗</title>
	<atom:link href="http://utweb.jp/blog/archives/author/masamune/feed" rel="self" type="application/rss+xml" />
	<link>http://utweb.jp/blog</link>
	<description>宇都宮さんっていう、夫婦でやってるウエブサイト制作請負の大阪下町家内製手工業業務日誌</description>
	<lastBuildDate>Thu, 02 Feb 2012 14:35:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/author/masamune/feed" />
		<item>
		<title>HTML5+Three.jsで3Dプログラミングに挑戦！</title>
		<link>http://utweb.jp/blog/archives/1330</link>
		<comments>http://utweb.jp/blog/archives/1330#comments</comments>
		<pubDate>Wed, 01 Feb 2012 09:31:43 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=1330</guid>
		<description><![CDATA[丸坊主なのに寝癖が付く男、正宗です。前回の記事「Actionscript3erが覚えるJavascriptでのクラス開発まとめ」でjavascriptをActionscript3ライクに書く方法をまとめてみたので、今度は [...]]]></description>
			<content:encoded><![CDATA[<p>丸坊主なのに寝癖が付く男、正宗です。<a href="http://utweb.jp/blog/archives/1281">前回の記事「Actionscript3erが覚えるJavascriptでのクラス開発まとめ」</a>でjavascriptをActionscript3ライクに書く方法をまとめてみたので、今度は練習がてらHTML5をさわってみました。</p>
<p>WebGL版です。<br />
<div id="attachment_1331" class="wp-caption alignnone" style="width: 310px"><a href="http://utweb.jp/test/html52/" title="Webかるた" target="_blank"><img src="http://utweb.jp/blog/wp-content/uploads/2012/02/a3c02fe803077ec2c342b35229b46313-300x205.png" alt="クリックで別ウインドウで開きます。" title="Webかるた" width="300" height="205" class="size-medium wp-image-1331" /></a><p class="wp-caption-text">クリックで別ウインドウで開きます。</p></div><br />
画像クリックすると別ウインドウで開きます。<br />
うまく動かない場合はWebGLを使わない素のCanvasレンダリングも作ってみましたので<a href="http://utweb.jp/test/html5/" target="_blank">こちらのリンク先</a>を参照してください。<br />
スクロールで3D空間をうねうね動く的なことがやりたいんだろうな、って思ってもらえたらうれしいです。ちなみに背景には旅行の思い出の写真をあしらって、ナイスな感じに仕上げました。<br />
ソースは適当にほじくって見てみてください。</p>
<p>今回は、はじめてHTML5を触ってみた中でわかったことを書きたいと思います。<br />
<span id="more-1330"></span><br />
HTML5でJavascriptからグラフィックを操作するには、従来のdivの操作に加えてSVGとCanvasを使う方法が加わったらしく、とりあえず今回はCanvasを使ってみました。</p>
<h3>3Dライブラリthree.jsについて</h3>
<p>ご存じのとおり、SVGはベクターを扱うタグでして、Canvasはピクセルを扱う場所になります。AS3だとベクターもラスターもどっちもよく扱うのでJSでも出来るんだろうけど流石に今回ピクセル操作ばっかりプログラミングするのは面倒くさかったので何かいいライブラリはないかと思っていると、どうやら3Dのライブラリ<a href="https://github.com/mrdoob/three.js/" target="_blank">three.js</a>が何やら面白そうです。<br />
ある程度のJavascriptの知識と、3Dライブラリを使ったプログラムの経験があればすんなりと使うことが出来ました。<br />
がんばってAPIを掘り下げれば、かなり面白いものが作れそうです。</p>
<p>注意すべき点は、たぶんバージョンアップのためだと思うのですがAPIの仕様が変わっていて、古い解説文書などですと動かない場合があることです。<br />
あとどうしてもドキュメントが少ないので、特にリファレンスが無いと何も出来ない僕にとっては、慣れ親しんだASDocくらい詳しいリファレンスが無いのが地味に大変でした。</p>
<p>ただし、クラス名やプロパティに変な癖も無いのでリファレンスが足りて無くても何とかなりました。<br />
一般的な3Dライブラリと似たような感じで</p>
<ul>
<li>シーンを作って、カメラを作って、レンダラーを作って</li>
<li>シーンや表示オブジェクトは入れ子構造にできて</li>
<li>ジオメトリとマテリアルを持つメッシュを作成して表示オブジェクトに追加</li>
<li>シーンとカメラを指定してレンダリングを実行</li>
</ul>
<p>という、ごくごく自然な流れでプログラミングできました。</p>
<p>面白いことに、WebGLでレンダリングするレンダラーと、素のCanvasにレンダリングするレンダラーがあるんですが、その二つをかなり簡単に切り替えられるんです。<br />
ここらへんは型付けがゆるいJavascriptならではの面白みだと思いました。</p>
<h3>制作環境について</h3>
<p>かなり残念な英語力と記憶力、たぐいまれなるタイピングミスの持ち主の僕にとって、開発環境こそが頼みの綱です。<br />
今回は<a href="https://twitter.com/#!/kotaro_tan" target="_blank">@kotaro_tan</a>さんに<a href="https://twitter.com/#!/masamunet/statuses/154863766771744768" target="_blank">教えて頂いた</a>WebStormというIDEを使ってみました。<br />
<div id="attachment_1332" class="wp-caption alignnone" style="width: 310px"><a href="http://utweb.jp/blog/wp-content/uploads/2012/02/13aaed03c6d403c190b9057b96e705b2.png" title="WebStorm"><img src="http://utweb.jp/blog/wp-content/uploads/2012/02/13aaed03c6d403c190b9057b96e705b2-300x217.png" alt="なにやらかっこいいクラスを作ってるなう" title="WebStorm" width="300" height="217" class="size-medium wp-image-1332" /></a><p class="wp-caption-text">なにやらかっこいいクラスを作ってるなう</p></div><br />
コードに色がたくさんついて綺麗なので気に入っています！</p>
<h3>Javascriptをクラスで開発していくことについて</h3>
<p><a href="http://utweb.jp/blog/archives/1281">前回の記事「Actionscript3erが覚えるJavascriptでのクラス開発まとめ」</a>でJavascriptでクラスを作って開発するスタイルをまとめてみたわけですが、手前味噌ながらこれが非常に役に立ちました。<br />
javascriptにはjavascriptの面白さがあるので、AS3のクラスっぽい作り方が無理矢理なのであれば何もわざわざjavascriptの面白さを消してまでクラス作りをする必要は全くないと思っていたのですが、無理矢理どころかむしろだいぶ自然にクラスが使えたので、だいぶ効率よく作ることが出来ました。<br />
後述するjsファイルの重複ロード問題も今回はクラスを使って解決できましたし、デザインパターンが使えるのもなによりうれしいひなまつりです（こんど娘が初節句なんです。楽しみで楽しみで）。<br />
クラスは僕も最初かなり苦手意識を持っていましたが、品質を上げるための先人の知恵の結晶なので今後ももっともっと勉強していきたいです。</p>
<h3>Javascriptのゆるさについて</h3>
<p>Javascript特有の「ゆるさ」は長所でもあり短所でもあるんですが、久々にまあまあの量のJavascriptをコーディングして、このゆるさもかなり楽しめました。<br />
個人的にはガチガチの型付け言語をガチガチのIDEで扱った方が実質的なコーディング速度は速いと思うんですが、Javascriptの設計のゆるさからくる「アイデアが形になるまでの速度感」はAS3とはまた違った面白さがあります。<br />
AS1の頃の面白さとHTML5の新鮮さの良いところどりはずるいと思います。</p>
<p>javascriptの楽しさをたっぷり楽しんだ上で、今後の課題も書き留めておきたいと思います。<br />
あくまでActionscript3よりな人間が久々に遊びでJavascript触ってみて対応というか妥協した程度の記録ですので、今後かならず解決するべきだしもっといいノウハウは他にあるはずです。</p>
<h4>変数やオブジェクトがいくらでも上書きできてしまう</h4>
<p>定数は無理としても、prototypeに閉じ込めるなどしてprivateな空間は作るべきなのでしょうが、今回はそこまでしませんでした。変数のアクセス範囲を出来るだけ狭くすることが鉄則なのに、非常に悩みどころです。</p>
<h4>名前空間について</h4>
<p>いちおう最初のファイルに</p>
<pre class="brush:javascript">if(!jp_utweb_namespace){
    var jp_utweb_namespace = {};
}</pre>
<p>こういう事書いておくことで「俺はグローバルの名前空間をあんまり汚染しない男だぞ」アピールをしているのですが、正直気に入っていません…。<br />
最低でもプロジェクトごとにも別けたいし、ネームスペースの変数名そのものを持ち回りたいんですが、そこらへんは今後の課題として残りました。</p>
<h4>重複ファイルのロードについて</h4>
<p>こういったjavascriptファイルがあったとして、<br />
onece.js</p>
<pre class="brush:javascript">;(function(ns){
    alert('一回しか実行を想定していない処理！');
})(jp_utweb_namespace);</pre>
<p>HTMLで二回読み込まれてしまうと</p>
<pre class="brush:html"><script type="text/javascript" src="onece.js"></script>
<script type="text/javascript" src="onece.js"></script></pre>
<p>当然二回実行されてしまいます。<br />
実行前にDOMを調べて、src属性に自分のファイル名と同じscriptタグが２つ以上ある場合は一回しか実行しない、といった処理をすればいいのですが、うまくライブラリ化できなかったので、それは今後の課題になります。</p>
<p>今回とった方法では、クラスを作成する処理ばかりにしておいて、最後にrun.jsというスクリプトファイルのみ、重複チェックを行って、ActionScriptでいうドキュメントクラスに相当するクラスを一回だけ実行する、というやり方にしました。</p>
<p>クラスを作成する直前に</p>
<pre class="brush:javascript">;(function(ns){
    if(!!ns.Mein){
        return;
    }
    ns.Main = functino(){};
})(jp_utweb_namespace);</pre>
<p>こんな感じでチェックを入れても良かったのですが、タイプミスなどによるデバッグがしづらくてかえって危険なのでやめました。<br />
実際に上のコードはこんなに短いのに見つけるのが困難なバグがあります。<br />
ここは素直に</p>
<pre class="brush:javascript">;(function(ns){
    ns.Main = functino(){};
})(jp_utweb_namespace);</pre>
<p>こう書くことにしました。<br />
重複ロード時にクラスが複数回生成されてしまうコストが発生しますが、プログラムの意図しない箇所でバグるよりはマシかと。</p>
<h3>まとめ</h3>
<p>いまのところまだちょっと触って遊んでみた程度ですので、今後案件に投入できるかどうかの判断もまだ現段階ではつきませんが、面白い技術であることには間違いないです。<br />
少なくともWEB上でリッチなインターフェースやモーション、体験を作るということにおいてはActionScripterこそ親和性の高い技術なので、これからどんどんと横断的に開発できるノウハウを見つけ出してハイブリッドな開発者がたくさん増えると面白いかと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/1330/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/1330" />
	</item>
		<item>
		<title>Actionscript3erが覚えるJavascriptでのクラス開発まとめ</title>
		<link>http://utweb.jp/blog/archives/1281</link>
		<comments>http://utweb.jp/blog/archives/1281#comments</comments>
		<pubDate>Sun, 29 Jan 2012 07:40:28 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=1281</guid>
		<description><![CDATA[カレーうどんが好きです。今日のお昼はカレーうどんでした。正宗です。
今日はJavascriptでクラス開発をしてみたいと思います。
冒頭のカレーうどんは関係ないですね。何かいわなきゃと思ってつい好物を出してみました。
ご [...]]]></description>
			<content:encoded><![CDATA[<p>カレーうどんが好きです。今日のお昼はカレーうどんでした。正宗です。<br />
今日はJavascriptでクラス開発をしてみたいと思います。<br />
冒頭のカレーうどんは関係ないですね。何かいわなきゃと思ってつい好物を出してみました。<br />
ご存じのとおり、Actionscriptはもともとバージョン1の頃はJavascriptとほぼ同じ言語であり、つまりAS1の頃のクラス開発がそのまま使える形となっています。</p>
<p>そこでJavascriptでクラスを作ったりするときに「あれ？ASだとこうやるやり方、JSだとどうやるんだっけ」ってのを減らせるように、完全に個人的な備忘録を作ってみました。自己流なうえにオレオレ規約ばっかりで恥ずかしい限りですがせっかく作って公開したのでなんらかのお役にたてばうれしいです。</p>
<p>Javascriptでのクラスの作り方は本当にたくさんの方法がありますが、その中で僕が一番馴染んでいる書き方だけを勝手に選んでのせています。<br />
さっきふと思い立ってやった方法をそのままばんばんのせている感じです。<br />
あと、JSとの類似性を浮き上がらせるためにASにはあえて型を宣言しないで書いています。<br />
ASやJSの綺麗なコードの書き方ではなく、あくまでもASに似せたやり方でJSを書いていく方法を探った記事ですのでご了承ください。<br />
あと、技術書でも何でもなくあくまで個人の備忘録ですので恥ずかしながら盛大に間違えている箇所がたくさんあるかと思います。その場合間違いは常に正していきたいのでご指摘頂けると大変嬉しいです。<br />
ほんと僕のブログ間違いもおおいんで前置きも長々となってしまってすいません。<br />
<span id="more-1281"></span></p>
<p>同じ処理を最初にAS3、次にJSの順番で書いてみたいと思います。</p>
<h3>クラスを使ってみる</h3>
<p>クラスを使う方法はまさに全く同じです。<br />
actionscript3</p>
<pre class="brush:as3">//インスタンスメンバを使う場合。
var d = new Date();
trace(d.getTime());
//クラスメンバを使う場合。
trace(Math.random());</pre>
<p>javascript</p>
<pre class="brush:javascript">//インスタンスメンバを使う場合。
var d = new Date();
console.log(d.getTime());
//クラスメンバを使う場合。
console.log(Math.random());</pre>
<p>つまり<strong>作り方の違いさえうまく吸収できれば、クラスを使うぶんにおいてはほぼ全くといっていいほど同じように使えるようになる</strong>ってことではあーりませんか。<br />
こりゃいいや、さっそく作り方をまとめてみよう。</p>
<h3>クラスを作ってみる</h3>
<p>AS3のほうは意図的にpackageブロックを書いていません。<br />
actionscript3</p>
<pre class="brush:as3">public class Human {
	public function Human() {}
}</pre>
<p>javascript</p>
<pre class="brush:javascript">/**
 * @constructor
 */
function Human(){};</pre>
<p>Javascriptではfunction宣言するだけでクラスが作れます。この部分がそのままコンストラクターになります。<br />
作ったクラスは先ほどみたいにASでもJSでも全く同じように</p>
<pre class="brush:as3">var John = new Human();</pre>
<p>こういうふうに使えるようになります。</p>
<h3>プライベートプロパティ、プライベートメソッドを作ってみる</h3>
<p>JSでは言語としてprivateをサポートしてないっぽい？<br />
言語がサポートしていない以上、なんとかして隠匿化するコードを書いた方が良いのかもしれませんが、個人的にはオリジナルで処理を組むよりは規約を作って<a href="http://code.google.com/intl/ja/closure/utilities/docs/linter_howto.html" target="_blank">こういったチェックツール</a>に頼る方が好みなので、JSのほうは<a href="http://cou929.nu/data/google_javascript_style_guide/#visibility-private-protected" target="_blank">Googleのコーディング規約を参考に</a>こうしてみました。<br />
まあClosure Linterまだ使ったことないですが。<br />
actionscript3</p>
<pre class="brush:as3">public class Human {
	public function Human() {}

	private var himitsu_ = 'わりと最近うんこをもらした';

	private function think_() {
		trace('（´-`）.｡oO（蛇口からビールが出ればいいのになあ…。');
	}
}</pre>
<p>javascript</p>
<pre class="brush:javascript">/**
 * @constructor
 */
function Human(){
    /** @private */ this.himitsu_ = 'わりと最近うんこをもらした';

    /** @private */ this.think_ = function() {
        console.log('（´-`）.｡oO（蛇口からビールが出ればいいのになあ…。');
    };
};</pre>
<p>JSのほうは、コンストラクタ内で宣言することで「これはプライベートな空間なんですよ」と（自分が）強く思い込むことにしました。</p>
<blockquote><p>2012/01/29 追記<br />
コンストラクタ内でvar で宣言しておいて、getter/setterで操作するってやり方を今知りました。うーん、それ使うかどうしようか迷う…。</p></blockquote>
<blockquote><p>2012/01/29 さらに追記<br />
さっそく<a href="https://twitter.com/#!/taikiken" target="_blank">@taikiken</a>さんからpublic/privateをわける方法を教えて頂きました。<br />
<a href="https://twitter.com/#!/taikiken/status/163534841021861889" target="_blank">ツイッター</a><br />
<a href="http://www.inazumatv.com/contents/archives/6350" target="_blank">JavaScriptでOOP – Classみたいなのにprivateな関数と変数 | イナヅマtvログ</a><br />
コンストラクタ内でvarでプライベート宣言しておいた上で、mainというfunctionもprivateで保持しつつそこのprototypeにpublicな変数と関数を入れておいてreturnするというやり方ですね（僕が言葉にするとかえってわかりにくいですが教えて頂いたコードはすごい明快です）。プロトタイプベースのクラス、奥が深い！</p></blockquote>
<h3>パブリックプロパティ、パブリックメソッドを作ってみる</h3>
<p>JSがprivateをサポートしていない（未確認）以上、publicもファブリックもあったもんじゃない（最近IKEAに行きました）のですが、JSのほうではprototypeに宣言することで「これはパブリックな空間にあるんですよ」と（自分が）強く思い込むことにしました。<br />
actionscript3</p>
<pre class="brush:as3">public class Human {
	public var syumi = 'プリクラ集め、水に向かって綺麗な言葉を言い続けること';

	public function work() {
		trace('|^o^|＜ひきこもりぎみなのでそとをあるくのはにがてです');
	}
}</pre>
<p>javascript</p>
<pre class="brush:javascript">/**
 * @constructor
 */
function Human(){};
/** @public */ Human.prototype.syumi = 'プリクラ集め、水に向かって綺麗な言葉を言い続けること';

/** @public */ Human.prototype.work = function() {
    console.log('|^o^|＜ひきこもりぎみなのでそとをあるくのはにがてです');
};</pre>
<h3>スタティックなプロパティやメソッドを作ってみる</h3>
<p>JSではクラス（正確にはFunctionオブジェクト？）に直接定義することでstaticになりました。<br />
actionscript3</p>
<pre class="brush:as3">public class Human {
	public static function help() {
		trace('困ったときはお互い様。');
	}
}</pre>
<p>javascript</p>
<pre class="brush:javascript">/**
 * @constructor
 */
function Human(){};
Human.help = function() {
    console.log('困ったときはお互い様。');
};</pre>
<p>助け合いの心は人が誰もが持っている心。美しいですね（美）</p>
<h3>継承してみる</h3>
<p>僕の作ったクラスがだいぶ人としても完成されてきた頃なので、ここらで継承して新たなクラスを作ってみたいと思います。<br />
actionscript3</p>
<pre class="brush:as3">public class Hentai extends Human{
	public function Hentai() {}

	public function zenra() {
		trace('╰⋃╯');
	}
}</pre>
<p>javascript</p>
<pre class="brush:javascript">/**
 * @constructor
 * @extends {Human}
 */
function Hentai() {};
Hentai.prototype = new Human();
Hentai.prototype.zenra = function() {
    console.log('╰⋃╯');
};</pre>
<p>Javascriptでは新たなクラスのprototypeにスーパークラスをインスタンス化させると継承できました。</p>
<h3>オーバーライドしてみる</h3>
<p>JSはそのまま親クラスを上書きするだけとしています。<br />
actionscript3</p>
<pre class="brush:as3">public class Hentai extends Human{
	public override function work() {
		//super.work();
		trace('三╰⋃╯');
	}
}</pre>
<p>javascript</p>
<pre class="brush:javascript">/**
 * @constructor
 * @extends {Human}
 */
function Hentai() {};
Hentai.prototype = new Human();
/** @override */ Hentai.prototype.work = function() {
    //this.constructor.prototype.work.call(this , arguments);
    console.log('三╰⋃╯');
};</pre>
<h3>インターフェースを使ってみる</h3>
<p>JSではインターフェースもサポートされていないので、インターフェースに似たふるまいをするコードを書くか書かないか、書くとしたらどこまで書こうか、ここ一番悩んだんですが、結局コードとしては一切書かないことにしました。<br />
だいたい<a href="http://code.google.com/intl/ja/closure/compiler/docs/js-for-compiler.html" target="_blank">この辺の記事</a>を参考に、規約で実現する方法を探っているところです。今のところコメントにinterfaceと書いてるだけですが。<br />
actionscript3</p>
<pre class="brush:as3">public interface IBijin {
	function yasashii();
	function iinioi();
}

public interface IIsya {
	function care();
}

public class Jyoi implements IBijin, IIsya{
	public function Jyoi() {}
	public function yasashii() {}
	public function iinioi() {}
	public function care() {}
}</pre>
<p>javascript</p>
<pre class="brush:javascript">/**
 * @interface
 */
function IBijin() {};
IBijin.prototype.yasashii = function() {};
IBijin.prototype.iinioi = function() {};

/**
 * @interface
 */
function IIsya() {};
IIsya.prototype.care = function() {};

/**
 * @constructor
 * @implements {IBijin, IIsya}
 */
function Jyoi() {};
Jyoi.prototype.yasashii = function() {};
Jyoi.prototype.iinioi = function() {};
Jyoi.prototype.care = function() {};</pre>
<p>こんな感じでしょうか？コードがなんかだいぶ投げやりになってきたなあ。</p>
<h3>さいごに</h3>
<p>僕がまとめた限りではまあだいたいこんなものではないでしょうか。<br />
無理矢理にしてまでJSをASのクラスライクに書いていく必要はないと思いますが、わりかし自然にASっぽく書くことも出来なくはなさそうな感じはします。<br />
今話題のArctic.jsやenchant.jsなど（ふたつとも僕はまだ残念ながら使えていないんですが）のようにASライクに書けるJSのライブラリも増えてきましたし、とりあえず横断的に開発してみたくてまとめてみました。<br />
ASもそうですがJavascriptも独学の完全自己流なので本当は晒せるほどは自信がないですが、何かしら役に立てばなによりです。</p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/1281/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/1281" />
	</item>
		<item>
		<title>ActionScriptとJavaScriptとの連携をまとめてみる</title>
		<link>http://utweb.jp/blog/archives/1230</link>
		<comments>http://utweb.jp/blog/archives/1230#comments</comments>
		<pubDate>Sat, 22 Oct 2011 16:53:22 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=1230</guid>
		<description><![CDATA[普段の仕事で「あ、これはブログに書き留めておこう」と思ったことの半分以上は、仕事の忙しさを理由になかなか書くことが出来なくて、それだけにこうして休日の夜中でもちょっとでも時間に空きがあればブログを書けることがどんなに嬉し [...]]]></description>
			<content:encoded><![CDATA[<p>普段の仕事で「あ、これはブログに書き留めておこう」と思ったことの半分以上は、仕事の忙しさを理由になかなか書くことが出来なくて、それだけにこうして休日の夜中でもちょっとでも時間に空きがあればブログを書けることがどんなに嬉しいか。<br />
妻の高校の頃のジャージがやけに似合う男、正宗です。<br />
今日は、ActionScript3のExternalInterfaceを使ってJavaScriptと連携する際の、普段から気をつけていることをまとめてみたいと思います。<br />
サンプルのソースは<a href="https://github.com/masamunet/ExternalInterface----" target="_blank">こちら、github</a>に置いてみました。<br />
<span id="more-1230"></span><br />
AS3でJSとイチャイチャするにはExternalInterfaceを使えばいいというのは周知の事実ですが、いろいろと気をつけておいた方が良いことがたくさんあります。<br />
特に長年やっててまとめようまとめようと思っていた箇所を、いったんここにまとめてみたいと思います。<br />
絶対に気を付ける点はこちらです。</p>
<ol>
<li>ObjectタグのIDのどこかに「external」を入れる。</li>
<li>Javascriptの名前空間を出来るだけ汚染しない。</li>
<li>初期化の実行順序を守る</li>
</ol>
<blockquote><p>2011/10/23 追記<br />
ひろゆきさんに教えていただいたんですが<a href="https://twitter.com/#!/ProjectNya/status/127790607954485248" target="_blank">（こちら）</a>、IDに「external」を付けなくても動くそうです。</p></blockquote>
<p>AS側でやっといて便利なのは次の点です。</p>
<ol>
<li>JavaScriptとの連携は必ずシングルトンを介して行う。</li>
</ol>
<p>順番にみてみたいと思います。</p>
<h3>Cap1.ObjectタグのIDのどこかに「external」を入れる。</h3>
<p><a href="http://utweb.jp/blog/archives/41">こちらの記事</a>にあるように、IEのアホウはトンマなヤロウであるわけです。<br />
本来ならばIEのマヌケなバグにこちらが付き合ってやるいわれはないわけですが、ObjectタグのIDのどこかしらに「external」と入れてやれば万事解決するのであれば、そうしてやろうではありませんか。<br />
それが大人というものではないでしょうか。<br />
なのでSWFObjectの記述はこんな感じになるかと思います。</p>
<pre class="brush:javascript">
;(function(){
	var swfDirectory = "/";
	var swfFileName = "index.swf";
	var targetId = "flashcontent";
	var width = "800";
	var height = "600";
	var version = "9.0.45";
	var expressInstall = swfDirectory+"commons/scripts/swfobject/expressInstall.swf";
	var flashvars = {};
	flashvars.jsNamespace = "jp_utweb_ExternalInterface_sample";
	var params = {};
	params.menu = "false";
	params.quality = "best";
	params.scale = "noscale";//showAll
	params.salign = "tl";
	params.wmode = "transparent";//opaque wmode
	params.swliveconnect = "true";
	params.allowfullscreen = "true";
	params.allowscriptaccess = "always";
	params.allownetworking = "all";
	var attributes = {};
	attributes.id = "external_content";
	attributes.name = "external_content";
	attributes.align = "middle";
	swfobject.embedSWF(swfDirectory+swfFileName, targetId, width, height, version, expressInstall, flashvars, params, attributes);
})();
</pre>
<p>まずは22行目、23行目、ObjectのID属性に「external」が出現していることに注目してください。<br />
10行目の</p>
<pre class="brush:javascript">
flashvars.jsNamespace = "jp_utweb_ExternalInterface_sample";
</pre>
<p>は次のCap2で説明します。</p>
<h3>Cap2.Javascriptの名前空間を出来るだけ汚染しない。</h3>
<p>基本的には匿名関数とか使って、ぱっと実行された間に必要なときだけ呼び出されてあとは何事もなかったかのようにぱっと消えるのは格好良いんですが、ASからJSを呼び出そうとした場合、いろいろ試してみたんですがどうしても最低ひとつはJSの名前空間を汚染する必要があるという結論に至りました。<br />
これに関しては結構いろいろためして、一見して無駄だと思えるような、匿名関数の中でSWFObjectを実行してその中でSWFはJS側の関数を呼ぶことで全く名前を消費しない方法を使えないかとかいろいろ試したのですが僕のスキルではどうにもならず、結果としてどうしても一個だけ名前を消費する方法しか作れませんでした。<br />
これがそのJavaScriptのテンプレートです。</p>
<pre class="brush:javascript">
;var jp_utweb_ExternalInterface_sample;
(function(){
	this.getElementFromName = function(name){
		if (navigator.appName.indexOf("Microsoft") != -1){
			return window[name];
		}else{
			return document[name];
		}
	};
	jp_utweb_ExternalInterface_sample = function(){};
	jp_utweb_ExternalInterface_sample.ready = function(){
		//ActionScriptが実行可能状態になったら最初に呼び出される。
		//JS側からAS側に関数を呼び出すときは必ずこの関数が実行された後にしなくてはならない。
	};
	jp_utweb_ExternalInterface_sample.hoge = function(){
		//ActionScriptから適時呼び出される。
		var swf = this.getElementFromName("external_content");
		if(swf){
			//ActionScriptの関数を実行。
			swf.asFunction();
		}
	};
})();
</pre>
<p>一行目の</p>
<pre class="brush:javascript">
;var jp_utweb_ExternalInterface_sample;
</pre>
<p>これが唯一の名前空間となります。<br />
これと全く同じ名前を、Cap1の10行目で</p>
<pre class="brush:javascript">
flashvars.jsNamespace = "jp_utweb_ExternalInterface_sample";
</pre>
<p>というふうにFlashに伝えてあることによって、Flash側ではJavaScriptへの呼び出しを可能にします。<br />
Flash側での呼び出しはCap4で説明します。</p>
<h4>コーヒーブレイク：ぼくのかんがえたさいきょうのJS名前空間</h4>
<p>一旦休憩です。<br />
非常にくだらない事を書くので、読み飛ばしてCap3まで進めることを強くおすすめします。<br />
僕がJavaScriptを触っていて特に気を遣うのが名前空間の汚染なわけですが、大規模案件にかかわらず一人で開発しているような趣味のプログラミングでもどうしてもグローバルの名前空間の汚染が避けられない状況がよく出てきます。<br />
僕は僕なりにいろいろ調べてはみたんですが、JavaScriptは言語仕様としてどうしてもこれは避けられないのではないかと思うようになったわけです。<br />
名前空間を擬似的に扱うクラスを作ってみたりもしたんですが、そのクラスに一つ名前空間を使うという仕様になってしまい、これはだめだということで他のアプローチで名前空間を確保する方法を考えてみました。</p>
<h5>1:僕を褒める言葉を使用する。</h5>
<p>調べてみたんですが、少なくともインターネット上では僕を褒める言葉が使われている回数は皆無なのですね。<br />
そこでこれを利用して僕を褒め称える変数名を使用すると、絶対に名前空間が保証されるというアイデアです。<br />
こんなふうに使います。</p>
<pre class="brush:javascript">
var 正宗さんは格好いい = "ほげ";
var 正宗さんの言うことは常に正しい = "ふが";
</pre>
<p>2行目のように、僕を恒常的に肯定する言葉を用いるとより強固になります。</p>
<h5>2:自作ポエムを変数名にする。</h5>
<p>変数名などを自作のポエムにすることで著作権によってプログラマーの死語50年間まで担保される非常に強固な名前空間を仕様することができます。<br />
この場合の名前空間の強度はディズニー法の強度に依存します。</p>
<pre class="brush:javascript">
var かにをたべ　るとくちのなか　かゆくなる = "hoge";
</pre>
<p>プログラムが一気に風流になるという副次的効果付きでとてもおすすめです。<br />
仕方のない話しはここまでにして、本題に戻ります。<br />
今まではSWFを表示させるためにブラウザ側やHTML側、JavaScript側の問題でしたが、次はActionScript側の問題になります。</p>
<h3>Cap3.初期化の実行順序を守る</h3>
<p>よっぽどの理由がない限り、JS側からAS側に働きかける場合、AS側が準備完了かどうかを待ってJSは働きかけたほうがより安全だと思います。<br />
つまりAS側が準備完了になった時点ではじめてJSに通知して、JSはその通知を待ってASに働きかけるようにするのが定石と言えます。<br />
Cap2の11行目から14行目</p>
<pre class="brush:javascript">
jp_utweb_ExternalInterface_sample.ready = function(){
 //ActionScriptが実行可能状態になったら最初に呼び出される。
 //JS側からAS側に関数を呼び出すときは必ずこの関数が実行された後にしなくてはならない。
};
</pre>
<p>を用意しておき、必ずActionScript側から最初に呼び出されてJSの初期化をここで行うようにします。<br />
ここまでが僕が作った必ず守るべきルールになります。<br />
次からはActionScript側からJSと連携するのに便利な方法をまとめたものになります。</p>
<h3>Cap4.JavaScriptとの連携は必ずシングルトンを介して行う。</h3>
<p>この記事の最初に提示したgithubのサンプルソースを見ていただくとわかりやすいんじゃないかと思うんですが、Javascriptとの連携はそれを専門にしたシングルトンクラスにまかせることにします。<br />
ちょっと簡単に書いてみます。<br />
ActionScript3です。</p>
<pre class="brush:as3">
package
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.external.ExternalInterface;

	public class JavascriptTool extends EventDispatcher
	{
		public static const DO_HOGEHOGE:String = "doHogehoge";
		public static const DO_FUGAFUGA:String = "doFugafuga";

		private static var _instance:JavascriptTool;

		private var _jsNamespace:String;

		public static function getInstance(jsNamespace:String = null):JavascriptTool
		{
			if(!JavascriptTool._instance){
				JavascriptTool._instance = new JavascriptTool(new Enforcer());
				if(!jsNamespace){
					throw new JsNamespaceError("Javascriptと連携する名前空間を指定してください。");
				}else{
					JavascriptTool._instance._jsNamespace = jsNamespace;
				}
				try{
					ExternalInterface.addCallback("jsHoge", JavascriptTool._instance.hogehoge);
					ExternalInterface.addCallback("jsFuga", JavascriptTool._instance.fugafuga);
				}catch(error:Error){

				}
			}
			return JavascriptTool._instance;
		}

		public function ready():void
		{
			try{
				ExternalInterface.call(_jsNamespace + ".ready");
			}catch (error:Error){

			}
		}

		public function hogehoge():void
		{
			dispatchEvent(new Event(DO_HOGEHOGE));
		}

		public function fugafuga():void
		{
			dispatchEvent(new Event(DO_FUGAFUGA));
		}

		function JavascriptTool(enforcer:Enforcer):void{}
	}
}
class Enforcer{}
class JsNamespaceError extends Error{
	public function JsNamespaceError(message:String):void
	{
		super(message);
	}
}
</pre>
<p>シングルトンの説明は省いたとして、これ。<br />
ExternalInterface.addCallback<br />
第一引数がJavascript側から見える関数。<br />
第二引数が実際のActionScriptの関数。<br />
APIとして多言語に対しての接続部分が隠匿化できるので非常に優れてるといえますけど作業する本人達にとってはややこしいことこの上ないです。<br />
この部分を埋めるデバッグツールは存在しないわけですし。<br />
そうは言ってもわざわざJS側とAS側で呼び出す関数名を指定できるってことはJS側とAS側で違う名前にしておいたほうがいいって事ですかね？<br />
僕はそう解釈して実行していますが、このへんの名前の命名規則になにか良い方法があったら教えていただきたいです。</p>
<p>あと21行目、他はイレギュラーな使われ方をしたときにわざわざコンパイルエラーを出すように作ってあるのに対して、この部分だけはランタイムエラーになるようにしか作れませんでした。<br />
シングルトンの生成される最初だけ値を渡して初期化したいときに、初期化のタイミングで値が渡されたときとそれ以外で値が渡されたときの両方でコンパイルエラーを出す何か上手い方法があればどなたか教えてください。</p>
<p>というわけでまだまだ未完成ながらもこのシングルトンクラスをいきなりドキュメントクラスで使ってみたのがこちら。<br />
ActionScript3です。</p>
<pre class="brush:as3">
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;

	public class externalinterfaceSample extends Sprite
	{
		private static const _DEFAULT_JS_NAMESPACE:String = "hogehoge_msturi";
		public function externalinterfaceSample()
		{
			if(stage){
				_init();
			}else{
				addEventListener(Event.ADDED_TO_STAGE, _init);
			}
		}

		private function _init(e:Event = null):void
		{
			if(!(!e)){
				removeEventListener(Event.ADDED_TO_STAGE, _init);
			}

			var tf:TextField = new TextField();
			tf.border = true;
			tf.autoSize = TextFieldAutoSize.LEFT;
			addChild(tf);

			var jsNamespace:String = _DEFAULT_JS_NAMESPACE;
			var flashVars:Object = stage.loaderInfo.parameters;
			if(!(!flashVars.jsNamespace) && flashVars.jsNamespace.length > 0){
				jsNamespace = flashVars.jsNamespace;
			}
			var jsTool:JavascriptTool = JavascriptTool.getInstance(jsNamespace);
			jsTool.ready();

			tf.text = "Javascriptからの呼び出しが実行可能になった。";

			jsTool.addEventListener(JavascriptTool.DO_HOGEHOGE, function(e:Event):void{
				tf.text = "JavascriptからjsHogeが呼び出された。";
			});
			jsTool.addEventListener(JavascriptTool.DO_FUGAFUGA, function(e:Event):void{
				tf.text = "JavascriptからjsFugaが呼び出された。";
			});
		}
	}
}
</pre>
<p>こんな感じでどこでもシングルトンクラスからJSを実行できるし、逆にJSからの呼び出しもいつでもどこでもEventを受け取る形でキャッチできるようになるんだよ〜、というサンプルでした。<br />
ActionScript、スマートすぎる。</p>
<p>このCap4は全てgithubのままですが、最後にいちおうgithubのindex.htmlのソースも載せておきます！</p>
<pre class="brush:html">
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja" dir="ltr">
<head>
	<title>ExternalInterfaceの実験</title>
	<script src="http://www.google.com/jsapi" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript">
		google.load("swfobject", "2.2"); 
	</script>
	<script type="text/javascript">
	;(function(){
		var swfDirectory = "./";
		var swfFileName = "externalinterfaceSample.swf";
		var targetId = "flashcontent";
		var width = "400";
		var height = "50";
		var version = "9.0.45";
		var expressInstall = swfDirectory+"commons/scripts/swfobject/expressInstall.swf";
		var flashvars = {};
		flashvars.jsNamespace = "jp_utweb_ExternalInterface_sample";
		var params = {};
		params.menu = "false";
		params.quality = "best";
		params.scale = "noscale";//showAll
		params.salign = "tl";
		params.wmode = "transparent";//opaque wmode
		params.swliveconnect = "true";
		params.allowfullscreen = "true";
		params.allowscriptaccess = "always";
		params.allownetworking = "all";
		var attributes = {};
		attributes.id = "external_content";
		attributes.name = "external_content";
		attributes.align = "middle";
		swfobject.embedSWF(swfDirectory+swfFileName, targetId, width, height, version, expressInstall, flashvars, params, attributes);
	})();
	</script>
	<script>
	;var jp_utweb_ExternalInterface_sample;
	(function(){
		this.getElementFromName = function(name){
			if (navigator.appName.indexOf("Microsoft") != -1){
				return window[name];
			}else{
				return document[name];
			}
		};
		jp_utweb_ExternalInterface_sample = function(){
			return {
				ready:this.reary,
				clickHoge:this.clickHoge,
				clickFuga:this.clickFuga
			};
		};
		jp_utweb_ExternalInterface_sample.ready = function(){
		};
		jp_utweb_ExternalInterface_sample.clickHoge = function(){
			var swf = getElementFromName("external_content");
			if(swf){
				swf.jsHoge();
			}
		};
		jp_utweb_ExternalInterface_sample.clickFuga = function(){
			var swf = getElementFromName("external_content");
			if(swf){
				swf.jsFuga();
			}
		};
	})();
	</script>
</head>
<body>
<div id="flashcontent"></div>


<input type="button" value="ほげ" onClick="jp_utweb_ExternalInterface_sample.clickHoge();" />
	
<input type="button" value="ふが" onClick="jp_utweb_ExternalInterface_sample.clickFuga();" />
</body>
</html>
</pre>
<p>ちょっと実験用に名前のスコープをいじっております。<br />
特にjp_utweb_ExternalInterface_sampleを返す48行目は、明示的にpublicな関数を指定してやるとJavaScript側からも実行できるようになります。</p>
<h3>まとめ</h3>
<p>やっと最近コードスニペットというのを覚えたので、コードの再生産がだいぶマシになりました。<br />
毎回毎回こんだけ再発明するのしんどいですもんね。<br />
まだまだ未完成な部分も多いですが、もっと上手い方法を随時見つけていきたいと思います！</p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/1230/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/1230" />
	</item>
		<item>
		<title>FlashのひよこがPixel Benderではじめる並列処理入門 後編</title>
		<link>http://utweb.jp/blog/archives/1158</link>
		<comments>http://utweb.jp/blog/archives/1158#comments</comments>
		<pubDate>Mon, 05 Sep 2011 16:51:37 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=1158</guid>
		<description><![CDATA[前編の続きです。

ではFlashで呼び出してみよう！
ここまでの道のりが長かったですね。安心してください。それまでのほとんどが僕のゴタクです。
僕がはじめるにあたって先ず理解しておかないといけないことが多すぎただけで、 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://utweb.jp/blog/archives/1071">前編の続き</a>です。<br />
<span id="more-1158"></span></p>
<h3>ではFlashで呼び出してみよう！</h3>
<p>ここまでの道のりが長かったですね。安心してください。それまでのほとんどが僕のゴタクです。<br />
僕がはじめるにあたって先ず理解しておかないといけないことが多すぎただけで、ほとんどの人は実際にはここまですいすいと来られたはずです。</p>
<p>PixelBenderのpbjファイルをFlashのActionScriptで使うには二種類の方法があります。<br />
実行時に外部ファイルとして読み込むか、Embedであらかじめ埋め込んでおくかです。</p>
<p>前者はXMLや外部JPEGファイルと同じく、URLLoaderを使って読み込む方法です。<br />
Progressionだとこんな感じで</p>
<pre class="brush: as3">
addCommand(
	new LoadURL(new URLRequest(Directory.PBJ_DIR + "myPixelBender.pbj"), {dataFormat:URLLoaderDataFormat.BINARY}),
	function():void{
		var t:Command = this as Command;
		_shader = new Shader(t.latestData);
	}
);
</pre>
<p>Progressionを介さずに普通にAS3で書く場合も、URLLoaderのdataFormatをちゃんとURLLoaderDataFormat.BINARYにしておけばうまくいくと思います。<br />
こんな感じ。</p>
<pre class="brush: as3">
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, _onCompleteHandler);
loader.load(new URLRequest(Directory.PBJ_DIR + "myPixelBender.pbj"));
private function _onCompleteHandler(e:Event):void
{
	var shader:Shader = new Shader(loader.data);
}
</pre>
<p>実際にはエラーハンドリングなんかも行う必要ありますがそれはまた別の話なのでここではあえて触れないでおきます。</p>
<p>Embedであらかじめ埋め込んでおく方法は、こんな感じで</p>
<pre class="brush: as3">
[Embed(source="/../shaders/myPixelBender.pbj", mimeType="application/octet-stream")]
private var _myPixelBenderKernel : Class;
private var _myPixelBenderShader : Shader;
</pre>
<p>クラスのインスタンス変数として埋め込んでおいて、適切な場所で</p>
<pre class="brush: as3">
_myPixelBenderShader = new Shader(new _myPixelBenderKernel());
</pre>
<p>として呼び出してやるやり方です。</p>
<p>実行時に外部ファイルとして読み込むか、Embedであらかじめ埋め込んでおくか、どちらのやり方もメリットデメリットあるので自分で適切だと思う方法で呼び出せばいいのですが、もしその判断が出来ない・迷うようであれば後者のEmbedで埋め込む方法をおすすめしておきます。<br />
シェーダーを外部読み込みにするメリットが思いつかないのであればほとんどの場合外部読み込みのデメリットのほうがEmbedする方法のデメリットを上回るからです。</p>
<h3>呼び出したのでどうやって使おう？</h3>
<p>2種類の呼び出しの方法のどちらを使っても、ActionScriptではShaderクラスとして読み込まれることがわかりました。<br />
<a href="http://help.adobe.com/ja_JP/FlashPlatform/reference/actionscript/3/flash/display/Shader.html" target="_blank">ここでActionScriptリファレンスのShaderクラスとそれに付随するShader何々クラスを一読しておくとだいたい何すればいいかわかるかと思います。</a><br />
僕みたいにクラスの動作が全て頭に入っているわけではないひよここそ、リファレンスの存在は欠かせません（いまだにArrayにさえ、こんなメソッド無いかな〜とリファレンス引きながら作業してるくらいです）。</p>
<p>FlashがPixelBenderをShaderで読み込んだら、いろいろ出来ることがあるんですが、いまのところ僕はShaderJobを使うことをおすすめします。<br />
理由としてはShaderJobが圧倒的に速いからです。<br />
ブレンドモードとして使ったり、塗りに使ったり、フィルタとして使ったり、も確かに面白いのですがそれらがどうしても最終的にFlashの処理を挟む必要があるのにたいして、ShaderJobは同じ事が出来てしかも完全にFlashと処理が切り離せるので「<strong>Flashの処理速度という概念を無かったことに出来る</strong>」という冒頭の売り文句が発揮できるからです。<br />
しかもFlashとの同期処理・非同期処理のどちらで処理するかを実行時に選べるのです。<br />
これのおかげでShaderJobを使うことによってFlashの描画処理を徹底的にチューニングすることが出来るようになると思います。僕もまだそこまでには達していませんが、少なくともその入り口には立てた気がします。</p>
<p>ShaderJobを使うには、まず入力側のBitmapDataと出力先のBitmapDataが必要になります。<br />
入力の指定については、PixelBenderのKernelの書き方によって違うのですが、</p>
<pre class="brush: as3">
_shader.data.src.input = _inputBitmapData;
</pre>
<p>こんな感じで指定してやります。<br />
「src」っていう変数名が、ここがKernelで使ってる変数名によって違うので注意が必要です。<br />
PixelBenderで<br />
input image4 src;<br />
と書かれてあれば</p>
<pre class="brush: as3">
_shader.data.src.input = _inputBitmapData;
</pre>
<p>と書きますし、もし<br />
input image4 sauce;<br />
だと</p>
<pre class="brush: as3">
_shader.data.sauce.input = _inputBitmapData;
</pre>
<p>こういう感じでActionScriptを書くようになるかと思います。</p>
<p>あとはShaderJobの処理のさせ方ですが、<br />
<a href="http://help.adobe.com/ja_JP/FlashPlatform/reference/actionscript/3/flash/display/ShaderJob.html" target="_blank">ShaderJobのリファレンスを読むと</a>コンストラクタの第二引数に出力先のBitmapDataを指定しないといけないことになっているのがわかります。<br />
そこでこんなふうに</p>
<pre class="brush: as3">
var _shaderJob:ShaderJob = new ShaderJob(_shader, _outputBitmapData);
</pre>
<p>ShaderJobクラスのインスタンスを生成します。<br />
そのあとおもむろに</p>
<pre class="brush: as3">
_shaderJob.start();
</pre>
<p>してやってもいいんですが、面白いことにShaderJobはstartする際に処理を非同期で実行するか同期して実行するかを選べます。</p>
<pre class="brush: as3">
//_shaderJob.start();
_shaderJob.start(false);
</pre>
<p>このいずれの場合も非同期で実行します。<br />
なので</p>
<pre class="brush: as3">
_shaderJob.addEventListener(ShaderEvent.COMPLETE, _onShaderJobCompleteHandler);
//_shaderJob.start();
_shaderJob.start(false);
</pre>
<p>こんな感じでイベントリスナーを登録しておくとシェーダーの処理が完了したタイミングを捕捉できるようになります。<br />
画面の処理のために入力や画面の更新などFlashの他の処理を遅らせたくない場合に、完全に処理を分離できるので非常に効果を発揮します。</p>
<pre class="brush: as3">
_shaderJob.start(true);
</pre>
<p>こうした場合には同期して実行します。<br />
どのみち同期しててもPixelBenderのShaderJobの処理はほとんどの場合は一瞬で終わるので誤差は一瞬ですが、画面更新のタイミングと処理を完全に同期させておきたい場合に効果的です。</p>
<h3>さいごに</h3>
<p>書いててほんと自分でもびっくりするくらい長い記事になったのですがどうでしょうか。<br />
ほとんどがPixelBenderの技術の話しではなくてPixelBenderとはどういう動作をするものなのかの概念の話しばかりだったと思います。<br />
それだけ僕にとってPixelBenderは概念的な障壁が高く、でも一旦概念を理解してしまえば技術的にそんなにハードルの高いものではない、むしろとっつきやすく奥の深いとても楽しいものだと言うことが解りました。<br />
それに一旦こうして記事にして書いてしまえば、次からPixelBenderの技術的な記事書くときに「概念についてはこちらを参考にしてください」と言えるので、むしろ今後PixelBenderを研究していく布石になったと思います。</p>
<p>僕がPixelBenderを学びはじめるに当たって参考にしたAS3アニメーションのオライリー本にも書かれてあることですが、PixelBenderはOpenGLのシェーダー言語GLSLに非常によく似た言語で、そのノウハウがだいぶ参考になるかと思います。</p>
<p>僕個人の考えとしては、ブラウザ上での描画に限って言えば並列処理を実現するための方法はさまざまに企画が立ち上がっていますが、3年以上も前から提供されていてしかもFlashさえ走ればブラウザを問わず納品レベルできちんと動くPixelBenderには一日の長があるかと思います。<br />
PixelBenderそのものが意外にもとっつきやすくて奥が深く、それでいてFlashが何十倍も楽しくなる面白い技術なのも今回学ぶに当たって新鮮な驚きでした。</p>
<p>この技術がもっと普及して研究がされたら、もっと面白い使いどころが増えると思いますし今までFlashの処理速度が枷だったことがいろいろと解決する可能性が高いかもしれません。<br />
今回の記事ではあえて書かなかったのですが、僕はPixelBenderをByteArrayとかVectorで処理する方法にも非常に興味を持っています。<br />
この記事がきっかけになって、少しでもPixelBenderの使いどころの上手い人が増えて今まで処理速度がネックになっていた問題が解決できれば、WEBの表現はもう一段階自由になるのではないでしょうか。</p>
<p>そこまでは夢見すぎだとしても、少しでも処理速度による表現の限界を解決するヒントになれば幸いです。</p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/1158/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/1158" />
	</item>
		<item>
		<title>FlashのひよこがPixel Benderではじめる並列処理入門 前編</title>
		<link>http://utweb.jp/blog/archives/1071</link>
		<comments>http://utweb.jp/blog/archives/1071#comments</comments>
		<pubDate>Mon, 05 Sep 2011 16:45:28 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=1071</guid>
		<description><![CDATA[最初ぼくPixelBenderのこと「pixel bLender」と勘違いしていました。
 証拠 
 証拠その2
 僕、得意げになって何か言ってますね…。終始間違いの多い男です。
  僕たちの失敗。こんばんは。森田童子で [...]]]></description>
			<content:encoded><![CDATA[<p>最初ぼくPixelBenderのこと「pixel b<strong>L</strong>ender」と勘違いしていました。<br />
 <a href="https://twitter.com/#!/masamunet/status/101699832657358848" target="_blank">証拠 </a><br />
 <a href="https://twitter.com/#!/zendenmushi/status/102767979346927617" target="_blank">証拠その2</a><br />
 僕、得意げになって何か言ってますね…。終始間違いの多い男です。<br />
  僕たちの失敗。こんばんは。森田童子です。嘘です。正宗です。</p>
<p> さてさて、今さらながらPixelBenderについて勉強してみました。PixelBenderって登場したの確か3年以上も前ですよねえ。<br />
普段から情報共有が 盛んなFlashにおいて、僕が今まで3年もPixelBenderを使っていなかった理由はひとえに「PixelBenderが何をするものなのかわかりにくい！」からでした。<br />
 PixelBenderを使うとどうなるのか、Flashのどんな場面で使えるのか、どうやって使うのか、いやいやそれ以前の問題でただひたすら「PixelBenderが何をするものなのかわかりにくい！」のでした。<br />
もちろん、Adobeの告知不足とかそういった事が言いたいわけではなくて、僕のスペックではPixelBenderはわかりにくいからとっつきにくかった。というお話です。</p>
<p>で、勉強してみてわかった結果は、「PixelBender、かなり使える」ということです。<br />
簡単に言うとFlashの処理能力が<strong>別次元</strong>で向上します。<br />
おおげさですがおおげさでない表現として「<strong>Flashの処理速度という概念を無かったことに出来る</strong>」ほどのパフォーマンスです。<br />
「別次元」とか「処理速度という考え方を無かったことに」というのは、太字にしたのは煽りでもなんでもなく実際に本当に処理方法が違うからです。これに関しても出来るだけ簡単に説明します。<br />
いったんサンプルを見てください。</p>
<div style="width:300px;height:200px;">
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="300" height="200" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://utweb.jp/samples/pixelbender_practice/index.swf" /><param name="allowFullScreen" value="true" /><embed type="application/x-shockwave-flash" width="300" height="200" src="http://utweb.jp/samples/pixelbender_practice/index.swf" style="width:300px;height:200px;" allowFullScreen="true"></embed></object>
</div>
<p>ウエブカメラがあれば接続の許可を求められると思いますので許可してください。<br />
ウエブカメラがない、あっても許可しなかった場合は、僕が今年の夏にバラ園にいったときの思い出の写真がかわりに表示されることになると思うので、そういった悲しい事故がないよう、是非ともウエブカメラを使って遊んで頂くことを強くおすすめします。</p>
<p>マウスをうごかしてもらうとわかると思うんですが、昔からよくある、水面の波紋のような画像処理を効果に加えたサンプルです。<br />
DisplacementMapFilterとかで手垢がつきまくっているので、アンテナの高い人には今さらなサンプルです。<br />
ここで見て貰いたいのは、処理のほとんどをPixelBenderにまかせたことによる処理速度の安定です。</p>
<p>サンプルのソースコードはこちら。<br />
<a href="https://github.com/masamunet/blog_samples_pixelbender_practice" target="_blank">https://github.com/masamunet/blog_samples_pixelbender_practice</a></p>
<p>ソースコードをみてもらってもわかるように、基本的に僕はなにもしていません。処理のほとんどを外部のPixelBenderファイルに頼っています。<br />
具体的には<a href="http://www.derschmale.com/2009/04/23/return-of-the-ripples-shallow-water-simulation-with-pixel-bender/" target="_blank">こちら</a>のソースをほとんどの部分で使用しています。<br />
僕がやったことと言えば、もともとDisplacementMapFilterで処理していた部分もShaderJobを用いてPixelBenderで行うように変更したくらいですが、そのPixelBenderも<a href="http://www.boostworthy.com/blog/?p=245" target="_blank">こちら</a>の記事を参考にしてあります。<br />
このように、PixelBenderの概念を一旦理解したら、あとは自分でオリジナルなPixelBender処理を書くもよし、海外にあるいろいろなPixelBenderのファイルを（ライセンスに従って）使いこなすも良し、いずれにせよ処理速度という表現の枷からかなり自由に解き放たれるPixelBenderは是非是非習得すべき楽しい技術だと思います。</p>
<p>ちなみにPixelBenderの習得にあたって参考にした本はこちら。<br />
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&nou=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=yamayu-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=4873114373" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe><br />
この本の第9章にPixelBenderについて書かれています。<br />
だからこの本以上のことはこのブログに書かれていないのでこの本を読んだ方はあんまり期待できる記事ではないと思いますが、PixelBenderについて僕なりに理解したことをまとめてみました。</p>
<p>PixelBenderはそんなに敷居の高い技術ではないです。<br />
実験レベルならすぐにはじめられて、効果は非常に高い（なにせ処理速度が別次元になるので）技術なので、ぜひともわかりやすく説明出来るようにまとめられたらと思います！<br />
<span id="more-1071"></span></p>
<p>とはいえさて何から書こう。<br />
やっぱり初心者にとってはそもそもまずPixelBenderが何かを知らないですよね。並列処理というちょっと特殊な処理の流れもあって、非常にとっつきにくい印象を受けるので、先ずはPixelBenderについて少し細かく説明してみたいと思います。<br />
なお、僕という初心者が理解した程度の説明を初心者を対象に説明するので情報の正確性については基本的に自信がないです。<br />
しかもピクセルシェーダーとかプログラマブルシェーダーと呼ばれる技術を意図的に全て「PixelBender」という名称を用いて説明しています。<br />
並列処理についても仮想化の話しとかまで説明し出すと僕が混乱するので、すべてハードウェアとして、つまり「並列処理を行う、そういう機械があるものとして」書いています。<br />
つまりここに書かれてあることをそのまま人に話すと笑われるかもしれないということです。</p>
<h3>はじめよう。先ず最初に、PixelBenderって何なん？</h3>
<p>PixelBenderとは、Adobeが開発したピクセルシェーダーを記述する言語のことです。その言語の記述やテスト、ビルドコンパイルするソフトのことをPixelBenderツールキットと呼びます。<br />
<div id="attachment_1099" class="wp-caption alignnone" style="width: 310px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/08/db155b9b01b4fc02f1ceb4d7198a374c.png" title="PixelBenderツールキット2"><img src="http://utweb.jp/blog/wp-content/uploads/2011/08/db155b9b01b4fc02f1ceb4d7198a374c-300x203.png" alt="画像はCS5についてきてたPixelBenderツールキット2" title="PixelBenderツールキット2" width="300" height="203" class="size-medium wp-image-1099" /></a><p class="wp-caption-text">画像はCS5についてきてたPixelBenderツールキット2</p></div><br />
ピクセルシェーダーとはある一つのピクセルを計算して描画するプログラムの事です。<br />
このブログのこの記事ではピクセルシェーダーとPixelBenderを意図的に「PixelBender」と統一して説明しています。それは例えば「スクリプト言語全般に言えることだけれどActionScriptに於いても同様に」とか説明していくとかえって混乱する場合が多いのと同じ理由で、ピクセルシェーダー全般のことなのかPixelBenderに限った事なのか、PixelBenderを習い始めたい初心者にとっては行きすぎた情報の正確性はかえって混乱すると思ったからです（そしてどのみちこのブログ記事に情報の正確性を求めても無駄だと僕が知っているからです）。</p>
<h3>なるほど、わからん。もっと簡単に説明して？</h3>
<p>そのためにはまず最初に「パソコンはどうやって画面が表示されるのかな？」について考えないといけません。<br />
PixelBenderは凄く簡単に言うと「ピクセルを処理する言語」、もっと限定的に言うと「画像を処理するための言語」だからです。</p>
<h3>ではパソコンはどうやって画面が表示されるのかな？</h3>
<p>パソコンの画面の最小単位は1pxからできていることは説明の必要がないと思います。<br />
では仮に1pxだけ表示するディスプレイがあるとして、その1pxに赤を表示させてみましょう。<br />
<div id="attachment_1133" class="wp-caption alignnone" style="width: 245px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/09/p1.png" title="p1"><img src="http://utweb.jp/blog/wp-content/uploads/2011/09/p1.png" alt="1ピクセルの画面に赤を描く" title="p1" width="235" height="231" class="size-full wp-image-1133" /></a><p class="wp-caption-text">1ピクセルの画面に赤を描く</p></div><br />
殴り書きの絵ですいません。<br />
こんな感じでCPUは赤を表示させています。<br />
ピクセルが増えて横に2ピクセルの画面ではどうでしょうか。<br />
<div id="attachment_1134" class="wp-caption alignnone" style="width: 292px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/09/p2.png" title="p2"><img src="http://utweb.jp/blog/wp-content/uploads/2011/09/p2.png" alt="CPUは1ピクセルずつ処理している" title="p2" width="282" height="226" class="size-full wp-image-1134" /></a><p class="wp-caption-text">CPUは1ピクセルずつ処理している</p></div><br />
あたりまえですがCPUは1ピクセルずつ描画を処理していることになります。<br />
ところで最近のディスプレイはかなり高解像度ですが、仮に620ピクセル×480ピクセルの画面を表示させようとするとCPUはどのように動いているでしょうか。<br />
<div id="attachment_1136" class="wp-caption alignnone" style="width: 269px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/09/p3.png" title="p3"><img src="http://utweb.jp/blog/wp-content/uploads/2011/09/p3.png" alt="620×480の画面に表示する" title="p3" width="259" height="248" class="size-full wp-image-1136" /></a><p class="wp-caption-text">620×480の画面に表示する</p></div><br />
一度に描画する処理の回数は解像度にそのまま匹敵するので620×480＝297600回の処理が必要になります。<br />
さらにこの画面を60フレームレートで動かそうと思うと297600×60＝17856000。一秒間に1千785万6千回ものCPUの処理が行われることになります。<br />
一個一個の処理は赤を出したり青を出したり程度なのでたいして重くない処理なのですが、コンピューターにとって画像の表示って意外と回数がかかる作業なのです。</p>
<p>こればっかりはCPUが進化して速くなっても、画面の表示処理だけはまともにやると解像度の処理回数がかかってしまうのはかつては避けられない問題でした。<br />
この問題を面白い方法で解決したのが次の考え方です。<br />
<div id="attachment_1137" class="wp-caption alignnone" style="width: 263px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/09/p4.png" title="p4"><img src="http://utweb.jp/blog/wp-content/uploads/2011/09/p4-253x300.png" alt="1ピクセルずつに専用のCPUを割り当ててしまう" title="p4" width="253" height="300" class="size-medium wp-image-1137" /></a><p class="wp-caption-text">1ピクセルずつに専用のCPUを割り当ててしまう</p></div><br />
「画像を表示させるための機械」を作ってその中に、620×480の画面なら、620×480個。つまりCPUを297600個並べて、それぞれ1ピクセルを描画すればいい、と。<br />
ものすごいパワープレイすぎてそんな馬鹿なと思うかもしれません。だいたいパソコンのCPUなんて安くても一個1万円くらいするのにそんなのを297600個も並べてどうすんねんと。<br />
その気持ちはよくわかります。ただ、画面表示専用のこのCPUは、一個一個は赤か青かとかを表示するだけなのですごく簡単な仕事を任されているのみなんです。このくらいの仕事なら僕にも出来るかもしれません。<br />
さらに普通のパソコンのCPUと違うところは、パソコンのCPUはそれこそ一秒間に何兆回、いやもっと処理を行わないといけないのにたいして、この画面表示専用のCPUは極端に言えば一秒間に60回だけ処理できればいいのです。それも物凄く簡単な仕事だけを。</p>
<div id="attachment_1138" class="wp-caption alignnone" style="width: 246px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/09/p5.png" title="p5"><img src="http://utweb.jp/blog/wp-content/uploads/2011/09/p5-236x300.png" alt="全ては同時に行われる" title="p5" width="236" height="300" class="size-medium wp-image-1138" /></a><p class="wp-caption-text">全ては同時に行われる</p></div><br />
色の出力しかできない簡単な処理を、しかも一秒間にたった60回しかできなくても、全ての処理は同時に行われるので一瞬で終わります。今までどんなに高性能なCPUでも処理回数がかかって仕方なかったところを、この画像処理の方法は一瞬で終わらせることができるのです。この「画像を表示させるための機械」はたいしたものです。</p>
<p>実際には本当に297600個も並べているのかというと半分本当で半分嘘になります。本当のところはもうちょっとソフトウェアやハードウェアレベルで仮想化なども行われているのですが、画像処理の並列処理についての考え方は基本的にこれまで説明したような処理で行われていることになります。<br />
しかもここまでの説明を「GPU」と説明すればわかるひとには一発でわかるものを、なぜ「仮想化とかそういう処理は置いておいて、「画像を表示させるための機械」というものがあることにしておく」などとまわりくどい説明を行ったかというと、PixelBenderはGPUが無くても動くからです。</p>
<h3>では改めて問う。PixelBenderとは何ぞや。</h3>
<p>PixelBenderとは、<br />
「つーかその1ピクセルごとに専用のCPUがあるならさ、そのCPUにプログラム走らせれば良いんじゃない？」という発想の元に生まれた、ピクセルを描画するためだけのプログラムです。</p>
<p>先ほど説明した「画像を表示させるための機械」が行っている1ピクセルの描画処理の流れはこんな感じです。<br />
<div id="attachment_1141" class="wp-caption alignnone" style="width: 260px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/09/p6.png" title="p6"><img src="http://utweb.jp/blog/wp-content/uploads/2011/09/p6.png" alt="1ピクセルの描画処理の流れ" title="p6" width="250" height="300" class="size-full wp-image-1141" /></a><p class="wp-caption-text">1ピクセルの描画処理の流れ</p></div><br />
これが620×480個、とにかく沢山並んでいて、一斉に、同時に、処理するんでしたね。<br />
これにPixelBenderというプログラムを走らせるとこうなります。<br />
<div id="attachment_1142" class="wp-caption alignnone" style="width: 260px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/09/p7.png" title="p7"><img src="http://utweb.jp/blog/wp-content/uploads/2011/09/p7.png" alt="PixelBenderの処理の流れ" title="p7" width="250" height="300" class="size-full wp-image-1142" /></a><p class="wp-caption-text">PixelBenderの処理の流れ</p></div>
<p>なんとなくPixelBenderというものがわかってきたでしょうか。<br />
冒頭（といっても記事の中盤）で説明した言葉をもう一回書いてみます。<br />
<strong>PixelBenderとはある一つのピクセルを計算して描画するプログラムの事です。</strong></p>
<h3>正体が分かればそんなに怖くない</h3>
<p>つまりPixelBenderが行う処理は、言ってしまえばRGBの値（正確にはあとアルファ値も）だけが入力されることと、出力もRGBの値（と正確にはあとアルファ値と）を出力するためだけのプログラムです。<br />
一個のプログラムは1ピクセルの色だけを出力するためのものです。<br />
そしてそれが何万個（場合によっては何千万個）も同時に実行されます。<br />
ActionScriptやJavaScriptなどのように、順番に実行される言語でプログラムしていると最初ちょっと戸惑いますが、PixelBenderは</p>
<ol>
<li>一個のピクセルを描画するためだけの言語
<ul>
<li>そしてそれだけしかできないのでたいして難しいわけではない</li>
<li>そもそも言語的にそれ以上の難しい事を出来るようにはなっていない</li>
</ul>
</li>
<li>全てが同時に実行される</li>
</ol>
<p>という二点のミソを理解すれば最初感じていた取っつきにくさは消え去りました。</p>
<h3>PixelBenderをFlashで使うことのメリット・デメリット</h3>
<p>そしてこのPixelBenderはFlashでもノーコストで使用できます。<br />
FlashのActionScriptにおいて、<br />
保守管理しやすい綺麗なコードを<strong>白魔法</strong><br />
高速化のために全てを犠牲にするような過激なチューニングが為されたコードが<strong>黒魔法</strong><br />
とするなら、PixelBenderはさしずめ<strong>召喚魔法</strong>です。<br />
全く異世界の力を借りることになり、威力は絶大。しかもノーコストです。</p>
<h4>メリット</h4>
<ul>
<li>同時に実行しなければならない処理がノーコストで一瞬にして終わる。</li>
<li>FlashのFPSを落とさない。</li>
</ul>
<p>実際にはFlashPlayerの実行環境の構成によりますが、理論上はFlashのFPSを落とすことはありません。</p>
<h4>デメリット</h4>
<li>PixelBenderの言語について多少なりとも習得が必要</li>
<li>処理できる型がBitmapDataかByteArrayに限られている</li>
<p>ByteArrayについてはまた別途書きます。</p>
<blockquote><p>2011/09/08追記<br />
<a href="https://twitter.com/#!/zahir1929/status/111511440271212544">ByteArrayと同じくVector.<Number>型も使えると教えて頂きました。</a></p></blockquote>
<p>ピクセルを描画するというPixelBenderの仕組み上、扱える描画オブジェクトがBitmapDataに限られます。<br />
BitmapData型を保持していない描画オブジェクトの場合、処理の前に常にbitmapData.draw()を発生させなければいけないので、このコストがいちばんの悩みどころになります。<br />
逆に言えば、BitmapData型を保持していればどんどん積極的にPixelBenderを使っていきたいところです。</p>
<h3>さっそく使ってみよう！PixelBender！</h3>
<p>とここまで書いておいてなんですが、悩んだんですがこの記事ではPixelBenderの言語については解説は書かないことにしました。<br />
理由は僕もまだはじめたばかりなので説明出来るほど言語にたいして理解が深くないためです。<br />
みなさんと同じく僕も目下勉強中なので、いずれ記事に出来るくらいには理解を深められたらと思います。</p>
<p>ただし、PixelBenderについては「PixelBender お目当ての処理」で検索するとけっこうな数で海外のPixelBenderのソースがヒットします。<br />
それらを参考にするも良し、ライセンス的に問題がないのであればそのままFlashに使用するもよしなので、およそ汎用的な処理であればPixelBender初心者でもかなりなことができてこの技術を手っ取り早く楽しむことは出来ます。</p>
<p>PixelBenderというプログラム言語についての解説は今回は省きますが、PixelBenderツールキットの使い方について、おおまかに説明してみたいと思います。<br />
ちなみに冒頭（といってもこの記事の中盤頃）でも書きましたがPixelBenderツールキットとはPixelBenderというプログラムを書いたり実行したりテストしたりコンパイルしたりするアプリツールのことです。Flashを作るあのソフトのことをFlashIDEと呼んだりするのと同じです。</p>
<p>PixelBenderツールキットは、AdobeCS4かAdobeCS5を買ってインストールしていれば標準で入っていると思います。CS5.5ではどうかわかりませんし、CS以外の他の方法で手に入れるやり方はわかりませんが、とにかくCSでインストールされているものとして話しをすすめてみます。<br />
ちなみにCS5ではPixelBenderツールキット2が入っていました。1と比べてどこか新しくなったんですかね？<br />
Macだと<br />
/アプリケーション/ユーティリティ/Adobe ユーティリティ<br />
/アプリケーション/ユーティリティ/Adobe ユーティリティCS5<br />
あたりに入ってると思います。</p>
<p><div id="attachment_1147" class="wp-caption alignnone" style="width: 310px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/09/p8.png" title="p8"><img src="http://utweb.jp/blog/wp-content/uploads/2011/09/p8-300x159.png" alt="New Kernelで新規作成" title="p8" width="300" height="159" class="size-medium wp-image-1147" /></a><p class="wp-caption-text">New Kernelで新規作成</p></div><br />
立ち上げるとメニューから「File」→「New Kernel」で新規作成です。<br />
PixelBenderのプログラムはこのKernelという単位で動きます。<br />
今までくどくど説明してきたように、このKernelという小さなプログラムが1ピクセルを描画するためのプログラムとなります。<br />
<div id="attachment_1099" class="wp-caption alignnone" style="width: 310px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/08/db155b9b01b4fc02f1ceb4d7198a374c.png" title="PixelBenderツールキット2"><img src="http://utweb.jp/blog/wp-content/uploads/2011/08/db155b9b01b4fc02f1ceb4d7198a374c-300x203.png" alt="画面は大きく3つにわかれています。" title="PixelBenderツールキット2" width="300" height="203" class="size-medium wp-image-1099" /></a><p class="wp-caption-text">画面は大きく3つにわかれています。</p></div><br />
画面は大きく3つに別れていて、上が画像の表示領域。<br />
下がプログラムのソースコードを書く場所、右側にいろいろな情報やパネルが並ぶようになっていると思います。<br />
このツールでPixelBenderの処理を書いたりテストしたりすることになります。<br />
プログラムはpbk（PixelBenderKernelFile）として保存されます。<br />
ひととおりプログラムを書いて満足できる結果が得られれば、さっそくFlashで使いたいと思います。その際はPixelBenderをFlashで使えるようにコンパイルしてやる必要があります。<br />
メニューの「File」→「Export Filter For Flash Player...」を選んでください。<br />
<div id="attachment_1148" class="wp-caption alignnone" style="width: 310px"><a href="http://utweb.jp/blog/wp-content/uploads/2011/09/p9.png" title="p9"><img src="http://utweb.jp/blog/wp-content/uploads/2011/09/p9-300x168.png" alt="Export For Flash Player..." title="p9" width="300" height="168" class="size-medium wp-image-1148" /></a><p class="wp-caption-text">Export For Flash Player...</p></div><br />
Flashでいうflaファイルがpbk。swfファイルがpbjファイルということになります。</p>
<p><a href="http://utweb.jp/blog/archives/1158">後半へ続きます。</a></p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/1071/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/1071" />
	</item>
		<item>
		<title>地獄のミサワ風WEBカメラの実験</title>
		<link>http://utweb.jp/blog/archives/1117</link>
		<comments>http://utweb.jp/blog/archives/1117#comments</comments>
		<pubDate>Sat, 03 Sep 2011 06:54:10 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=1117</guid>
		<description><![CDATA[正宗です。
今日の飲み会用に作ったネタです。
Webカメラから顔を認識して自動的に中央に寄せる実験です。
まだまだ処理が甘いけれど一旦公開。



DisplacementMapFilterのマップ作りに手こずった。
ソ [...]]]></description>
			<content:encoded><![CDATA[<p>正宗です。<br />
今日の飲み会用に作ったネタです。<br />
Webカメラから顔を認識して自動的に中央に寄せる実験です。<br />
まだまだ処理が甘いけれど一旦公開。</p>
<p><span id="more-1117"></span></p>
<p style="width:240px;height:320px;"><embed type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="/samples/misawacam/index.swf" width="240" height="320" play="true" loop="true" menu="true"></embed></p>
<p>
DisplacementMapFilterのマップ作りに手こずった。<br />
ソースコードは<a target="_blank" href="https://github.com/masamunet/misaka_cam">こちら</a>。&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/1117/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/1117" />
	</item>
		<item>
		<title>釣りタイトル「HTML5 v.s. Flash」ついて。</title>
		<link>http://utweb.jp/blog/archives/1050</link>
		<comments>http://utweb.jp/blog/archives/1050#comments</comments>
		<pubDate>Tue, 23 Aug 2011 18:56:21 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=1050</guid>
		<description><![CDATA[僕はウエブサイト制作請け負いを生業としていまして、毎日いろんなウエブサイトを、大阪の隅っこの方で家内とたった二人でこしらえています。
一度でもお会いした方には、求められれば今まで制作した実績を、秘密保持の契約に問題ない範 [...]]]></description>
			<content:encoded><![CDATA[<p>僕はウエブサイト制作請け負いを生業としていまして、毎日いろんなウエブサイトを、大阪の隅っこの方で家内とたった二人でこしらえています。</p>
<p>一度でもお会いした方には、求められれば今まで制作した実績を、秘密保持の契約に問題ない範囲でお知らせしていますのでご存じの方も多いですが、ウエブサイト制作という目的に沿うためのありとあらゆる技術を駆使して業務に携わっており、その中でもとりわけFlashが大好きな、いわゆる業界の一部のみで使われるスラングであるところのFlasherという肩書きを好んで自称しております。</p>
<p>ここ数年でよく目にするようになった「HTML5 v.s. Flash」という言葉。<br />
別に個人の話しレベルでは何も思うことはなかったのですが、特にここ最近は大手技術系ニュースブログでもたぶんアクセス数欲しさからやってることなのだとは思いますが釣りタイトルで使われるようになり、ちょっと個人的に看過できないのではないかと考えるようになってきました。</p>
<p>ニュースブログのやってることは、記事という名の広告掲載場所を作るためのいわゆる看板板の作成のお仕事なので、釣りタイトルで人目を引くことに関しては何も異論はありません。<br />
何ズモードとか何デア何デアとか、けっこうかなりな大手ニュースブログで勝手に「もうFlashはいらない？」と煽られたFlashを、こよなく愛するいちユーザーが感じた、ちょっとした違和感を書きたいと思います。</p>
<p><span id="more-1050"></span></p>
<h3>大前提としてFlashとHTML5は対立関係に無い。排他的関係はもっと無い。</h3>
<p>「もうFlashはいらない？」</p>
<p>これわざとなんですかねえ。わざとなんですよねえ。何イデアアイデアさんとか何ズモードジャパンさんとか大手でもやってますが。</p>
<p>もしわざとでないんであれば、後述するようにもうニュースサイトの記事書くのやめたほうがいいですし、わざとなんであれば、アクセス数をすこしでも稼ぎたいお気持ちはすごくよくわかります。</p>
<p>もしかしたらFlashを触ったこともないような人とか、HTMLに全く理解の無い人からはあたかも対立関係があるように見えるのかもしれませんが、僕程度の半可通からみても対立するような技術ではないことはよくわかります。<br />
少なくとも僕の知ってるHTML5を研究してる人やFlashの凄い人や、誰に聞いても「むしろどこがどう対立するのかこっちが知りたい」という意見しか聞こえてこないです。<br />
何故「HTML5 v.s. Flash」という図式が外野で作られたのか。<br />
それには三つの本当とたった一つの勘違いがあるからだと僕は考えています。</p>
<h3>[本当.1]AppleとAdobeは対立しているように見える。</h3>
<p>これは本当だと思います。<br />
MacのOSアップデートLionのときにAdobeのアプリがことごとく動かなかった事から見ても、相当根が深いのかなと心配しています。</p>
<h3>[本当.2]AppleはiOSにFlashを搭載する予定はないし、その代わり「HTML5が動くよ」と言う。</h3>
<p>これも本当です。<br />
iOSではFlashのリッチな体験が出来ない問題に対してHTML5がその役割を代替することをアップルは期待しています。</p>
<h3>[本当.3]AdobeはiOSにFlashPlayerが走らないと困る。</h3>
<p>本当そうですよね。<br />
ただ、これが次の勘違いを生むことになります。</p>
<h3>[勘違い.1]AdobeはHTML5が普及すると困る。</h3>
<p>完全に勘違いです。<br />
Adobeが困るのはFlashPlayerが走らない環境が少なくなるのが困るのであって、つまりiOSでFlashPlayerが走らないことについては非常に困っています。<br />
2番目の本当でAppleがiOSのFlashの代替にHTML5を提示したこともあって、FlashとHTML5を同等に並べられて勘違いされやすいですが、iOSでFlashが動かないのはAdobeにとって大問題ですが、HTML5の普及とAdobeは何の関係もないんです。<br />
むしろ、クリエイターに制作ツールを売って生計を立てているAdobeにとって、クリエイターに支持されるHTML5のツールを作ることは至上命題なのです。<br />
ちょっとややこしいですが、</p>
<ol>
<li>iOS =&gt; HTML5好き　Flash無理</li>
<li>Adobe =&gt; Flashが動かないのは嫌！iOSでも動かして！</li>
<li>Apple =&gt; 嫌。Flashの代わりにHTML5動くし。</li>
</ol>
<p>というなりゆきと</p>
<ul>
<li>Adobe =&gt; クリエイターが使うツールを作って売ってる会社</li>
</ul>
<p>とはわけて考える必要があります。<br />
Adobeの顧客であるクリエイター、そのクリエイターの最近の出力先として無視できないのがWEB。<br />
WEBの出力先として無視できないのがiOS。<br />
iOSのWEBでFlashが動かない事は、Adobeのプラットフォーム戦略としては問題です。<br />
が、AdobeがHTML5のツールを出すことについてAdobeにとって特に何も問題になることはありません。</p>
<p>ということでAdobeがiOSでFlashPlayerが動かないのは困りものです。</p>
<p>でもそれ以外が全然的外れな感じがしないですか？<br />
問題がややこしいから普通に会話で「HTML5 v.s. Flash」とか言っちゃうのはわかるんだけれど、少なくとも大手といわれる技術系記事を書いて広告掲載場所を少しでも多く稼いでる看板板屋としては、素で勘違いしていたのであれば技術系の話題を書く素質無しだし、わざとやってたのだとしたらそうとうにあざといとは思います。<br />
わざとだとすれば、僕は大手のブログの記者に、アクセス数欲しさに「Flashはもう必要なし？」とまで煽られたので、少しは文句も言っていいでしょうか？</p>
<p>大手の知名度の割にはアクセス数が厳しいのか多少でも過激なタイトルをつけないといけない事情はわかります。<br />
「もうFlashはいらない？？？？？Adobeが作ったHTML5でFlash終了pgr」<br />
と煽って記事を書かないといけない心中はお察ししますが、僕がいちばん腑に落ちないのは<br />
いったいぜんたい何を持ってして、HTML5の表現力を引き出すツールができたからといってFlashがいらないと判断したかです。<br />
少なくともFlashを煽れば、記事にアクセスがつくと思ったのでしょうか？</p>
<h3>「もうFlashはいらない？？」</h3>
<p>もうFlashはいらないんでしょうか？</p>
<p>ナニを持ってしてそう感じたかは、僕が聞きたいくらいでが、ナニアイデアだったかナニギズモードだったかの記事では、彼らは「もうFlashはいらない」と感じたようです。</p>
<p>しかしながら僕はそう考えていません。<br />
今までFlashにしか出来なかった表現が（CSS3と組み合わせることで）HTML5でも出来るようになった。<br />
素晴らしいことです。<br />
Flashで培った表現が、より多くの人に見てもらえるプラットフォームが広がったのです。<br />
HTMLでできたサイトが動くようになったのです。</p>
<p>ねんがんの、動くサイトがやっと陽の目を浴びることになったのです。<br />
動くサイトは魅力的です。<br />
ユーザーにとって凄くわかりやすいです。<br />
「WEBサイトとはこういうものだから」という技術者の言い訳を超えた、<br />
「ページが切り替わるなら（うっとうしいと感じない範囲で）切り替わりのアニメーションをする、<br />
ボタンを押したら切り替わる、<br />
フリックしたら画面が指についてくる、<br />
といったように、ユーザーにとってわかりやすい制作物を作るためにアニメーションは絶対に欠かせません！</p>
<p>何デアアイデアとかいう超有名ブログとか何モードジャパンとか国際的に凄いか知らないですが彼らが言うには、なんかどうもFlashはいらないらしいです。ですが僕には納得できません。</p>
<p>僕が納得できないことと言うのは、つまり僕が知らないいろいろな事を相手は知っているという事で、もの凄く勉強のチャンスを得たと喜んでいます。</p>
<p>是非ともお話をお伺い存じたく奉りござ候でございますが、まあどうでもいいので、もしアクセス欲しさに「Flashはもういらない？」とかタイトルを 書いたのであればちょっとでも恥ずかしいと思ってくれたらそれでいいわけです。</p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/1050/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/1050" />
	</item>
		<item>
		<title>ひよこの会でやったトゥイーンの再利用</title>
		<link>http://utweb.jp/blog/archives/1019</link>
		<comments>http://utweb.jp/blog/archives/1019#comments</comments>
		<pubDate>Wed, 29 Jun 2011 02:56:19 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=1019</guid>
		<description><![CDATA[お父さんです。
 先日行われた勉強会、ひよこの会で発表してきた「トゥイーンの再利用」についてまとめました。 僕自身、トゥイーンの再利用についてまだあまり有効な活用方法を見いだせておらず、いちおうずっと気になってた方法をま [...]]]></description>
			<content:encoded><![CDATA[<p>お父さんです。<br />
 先日行われた勉強会、<a target="_blank" href="http://www.project-nya.jp/modules/weblog/details.php?blog_id=1442">ひよこの会</a>で発表してきた「トゥイーンの再利用」についてまとめました。 僕自身、トゥイーンの再利用についてまだあまり有効な活用方法を見いだせておらず、いちおうずっと気になってた方法をまとめるだけの発表でしたが、仕事の時短術やクオリティアップにお役に立てれば幸いです。<br />
<span id="more-1019"></span><br />
Flashには昔から（たぶんFlash8とかの旧モーショントゥイーンの時代から）トゥイーンを再利用する方法が幾つか用意されてあり、その後になって新モーショントゥイーンの機能も追加されたこともあって本当にたくさんのトゥイーンの再利用方法が用意されています。<br />
僕はトゥイーンの再利用そのものに有効な活用方法を見いだせないままずっと放置していたのですが、これを機会に調べられるだけ調べてみました。</p>
<p><embed type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" src="http://utweb.jp/blog/wp-content/uploads/test.swf" width="300" height="200" play="true" loop="true" menu="true"></embed></p>
<p>仮にこんなすばらしいモーションを作ったとします。このすばらしいモーションを出来るだけ後生にまで伝えたい、素材を変えてモーションだけ再利用したい！<br />
そんな願いを叶える方法です。<br />
いちおうほとんど全て新モーショントゥイーンを対象に説明していますが、僕も今回やっと新モーショントゥイーンちょっと触った程度なので、旧モーショントゥイーンの再利用方法についても一番最後に説明をしておきます。</p>
<h3>１：コピー&ペーストして再利用</h3>
<p>一番簡単な方法がこれだと思います。<br />
モーションガイドを選択した状態で右クリックして<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/2150746de01c41a107f05480e8416afd.png" title="モーションをコピー"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/2150746de01c41a107f05480e8416afd-300x171.png" alt="モーションをコピー" title="モーションをコピー" width="300" height="171" class="alignnone size-medium wp-image-1027" /></a><br />
「モーションをコピー」を選びます。<br />
これでモーションがクリップボードにコピーされましたので、次は<br />
別の素材を選択して右クリックから<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/0ba40aeaebe42909634ae283145f5abd.png" title="モーションをペースト"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/0ba40aeaebe42909634ae283145f5abd-300x170.png" alt="モーションをペースト" title="モーションをペースト" width="300" height="170" class="alignnone size-medium wp-image-1025" /></a><br />
「モーションをペースト」するだけでOKです。</p>
<h3>２：モーションプリセットに保存して再利用</h3>
<p>クリップボードにコピーしただけでは、このすばらしいモーションは保存されません。<br />
何度も何度も、繰り返し再利用したいモーションはこのプリセットに保存する方法を使うといいかと思います。<br />
モーションを選択して右クリック<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/1d102a0f7a3bf728cbdca1a209a1fb0f.png" title="モーションプリセットとして保存"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/1d102a0f7a3bf728cbdca1a209a1fb0f-300x162.png" alt="モーションプリセットとして保存" title="モーションプリセットとして保存" width="300" height="162" class="alignnone size-medium wp-image-1029" /></a><br />
「モーションプリセットとして保存」<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/1fa01ab79dff42c99660bed49fb6f84b.png" title="プリセット名を入力"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/1fa01ab79dff42c99660bed49fb6f84b-300x118.png" alt="プリセット名を入力" title="プリセット名を入力" width="300" height="118" class="alignnone size-medium wp-image-1030" /></a><br />
プリセットに名前をつけろと言われるので、世界であなたのモーションだけの素晴らしい名前をプレゼントしましょう。<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/d8155f694107adc76b33a7616ca1b0b4.png" title="モーションプリセット"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/d8155f694107adc76b33a7616ca1b0b4-300x187.png" alt="モーションプリセット" title="モーションプリセット" width="300" height="187" class="alignnone size-medium wp-image-1032" /></a><br />
保存したモーションはメニューの「ウインドウ」→「モーションプリセット」からいつでも呼び出せることが出来ます。<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/2eee2d36859efe50348fb8ddde420519.png" title="プリセット"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/2eee2d36859efe50348fb8ddde420519-300x227.png" alt="プリセット" title="プリセット" width="300" height="227" class="alignnone size-medium wp-image-1033" /></a><br />
自分が保存したモーションの他にも、「デフォルトプリセット」といってAdobeがあらかじめ用意した<del datetime="2011-06-29T01:27:23+00:00">使いどころの難しい</del>僕のモーションよりもずっと素晴らしいプリセットもあります。</p>
<p>ちなみに、モーションプリセットの具体的な保存場所は、<br />
Macだと<br />
/Users/＜ユーザー名＞/Library/Application Support/Adobe/Flash CS5/ja_JP/Configuration/Motion Presets<br />
winだと<br />
C:\Users\＜ユーザ名＞\AppData\Roaming\Adobe\Flash CS5\ja_JP\Configuration\Motion Presets<br />
あたりにあるのではないでしょうか（Winは未確認）。<br />
adobe系のこういったユーザー定義ファイルの保存場所は覚えておくと何かと便利です。</p>
<h3>３：AS3のコードとして再利用</h3>
<p>実用的かどうかはまだ未知数なのですが、僕が一番おもしろいなと思ったのがこれです。<br />
モーションをActionScript3.0のコードに変換してしまう方法です。<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/fddd2a89d4876a534c245f4e7e71f39e.png" title="as3.0にモーションを書き出してコピー"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/fddd2a89d4876a534c245f4e7e71f39e-300x176.png" alt="as3.0にモーションを書き出してコピー" title="as3.0にモーションを書き出してコピー" width="300" height="176" class="alignnone size-medium wp-image-1035" /></a><br />
モーションを選択後右クリックで「as3.0にモーションを書き出してコピー」<br />
これで今選択したモーションがクリップボードにActionScriptのコードとしてコピーされました。<br />
試しにタイムラインにアクションスクリプトをペーストしてみましょう。<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/78f2d2a31e0e99005f64f389181b7e3e.png" title="任意のタイムラインを選択してアクションパネルを開きます。"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/78f2d2a31e0e99005f64f389181b7e3e-273x300.png" alt="任意のタイムラインを選択してアクションパネルを開きます。" title="任意のタイムラインを選択してアクションパネルを開きます。" width="273" height="300" class="alignnone size-medium wp-image-1037" /></a><br />
任意のタイムラインを選択してアクションパネルを開きます。<br />
そこでおもむろにペーストしてみてください。</p>
<pre class="brush: as3">
import fl.motion.AnimatorFactory;
import fl.motion.MotionBase;
import fl.motion.Motion;
import flash.filters.*;
import flash.geom.Point;
var __motion_kao_5:MotionBase;
if(__motion_kao_5 == null) {
    __motion_kao_5 = new Motion();
    __motion_kao_5.duration = 35;

    // Call overrideTargetTransform to prevent the scale, skew,
    // or rotation values from being made relative to the target
    // object's original transform.
    // __motion_kao_5.overrideTargetTransform();

    // The following calls to addPropertyArray assign data values
    // for each tweened property. There is one value in the Array
    // for every frame in the tween, or fewer if the last value
    // remains the same for the rest of the frames.
    __motion_kao_5.addPropertyArray("x", [0,5.96283,12.2405,18.8772,25.9359,33.4796,41.634,50.516,60.2874,71.1639,83.2892,96.5736,110.379,123.662,135.795,146.678,156.446,165.326,173.477,181.017,188.073,194.706,200.98,206.95,188.338,169.716,151.072,132.439,113.806,95.1561,76.5351,57.9093,39.2788,20.6491,2]);
    __motion_kao_5.addPropertyArray("y", [0,-12.4844,-24.8276,-36.9843,-48.9072,-60.5021,-71.7026,-82.3267,-92.1163,-100.674,-107.31,-111.064,-111.069,-107.324,-100.691,-92.1305,-82.3435,-71.7214,-60.5223,-48.9285,-37.0062,-24.8498,-12.5067,0,-0.258063,-0.404897,-0.470401,-0.473853,-0.429182,-0.347192,-0.237801,-0.111154,0.0184064,0.120505,0]);
    __motion_kao_5.addPropertyArray("scaleX", [1.000000]);
    __motion_kao_5.addPropertyArray("scaleY", [1.000000]);
    __motion_kao_5.addPropertyArray("skewX", [0]);
    __motion_kao_5.addPropertyArray("skewY", [0]);
    __motion_kao_5.addPropertyArray("rotationConcat", [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
    __motion_kao_5.addPropertyArray("blendMode", ["normal"]);
    __motion_kao_5.addPropertyArray("cacheAsBitmap", [false]);

    // Create an AnimatorFactory instance, which will manage
    // targets for its corresponding Motion.
    var __animFactory_kao_5:AnimatorFactory = new AnimatorFactory(__motion_kao_5);
    __animFactory_kao_5.transformationPoint = new Point(0.500000, 0.500000);

    // Call the addTarget function on the AnimatorFactory
    // instance to target a DisplayObject with this Motion.
    // The second parameter is the number of times the animation
    // will play - the default value of 0 means it will loop.
    // __animFactory_kao_5.addTarget(&lt;instance name goes here&gt;, 0);
}
</pre>
<p>なにやらぞわーっとスクリプトが貼り付けられました。<br />
今自分が作ったモーションがActionScriptに変換されたことが分かります。<br />
あとは動かしたいインスタンスにインスタンス名をつけてやって（今回は「icon」とつけました）<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/eb1e2e3d7447ad41ada99b652f4c9188.png" title="インスタンス名「icon」とつけてみる"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/eb1e2e3d7447ad41ada99b652f4c9188-300x125.png" alt="インスタンス名「icon」とつけてみる" title="インスタンス名「icon」とつけてみる" width="300" height="125" class="alignnone size-medium wp-image-1039" /></a><br />
39行目の箇所の</p>
<pre class="brush: as3">
    // __animFactory_kao_5.addTarget(&lt;instance name goes here&gt;, 0);
</pre>
<p>こうなってる箇所のコメントアウトを外して、addTargetの一番目の引数に先ほどの動かしたいインスタンスのインスタンス名を入れてやります。</p>
<pre class="brush: as3">
    __animFactory_kao_5.addTarget(icon, 0);
</pre>
<p>いろいろごちゃごちゃと書かれていますが、ほとんどが動きの定義ばっかりで、実際に実行しているのはこの最後の一行だけです。</p>
<p>この機能、まだ調べたわけではないのであれなんですが、憶測では結構低レベルのAPI叩いてるっぽくて、うまくオレオレモーションライブラリと組み合わせるとお気に入りの軽い動作が出来るんじゃないかとほくそ笑んでます。</p>
<h3>４：XMLとしてモーションをコピーして再利用する</h3>
<p>今までは新モーショントゥイーンでの再利用方法だったわけですが、最後にもう一つ、旧モーショントゥイーンでも使える再利用の仕方も調べてみました。<br />
それがこのXMLとしてモーションをコピーして再利用する方法です。<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/e75738789eafdf08c0f2c0197a9d28ff.png" title="XML形式でモーションをコピー"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/e75738789eafdf08c0f2c0197a9d28ff-300x184.png" alt="XML形式でモーションをコピー" title="XML形式でモーションをコピー" width="300" height="184" class="alignnone size-medium wp-image-1045" /></a><br />
クラシックトゥイーンでモーションを作ったら、タイムライン上でコピーしたいフレームを全選択しておいて<br />
「コマンド」→「XML形式でモーションをコピー」を選びます。<br />
これでモーションがXMLの形式でクリップボードにコピーされました。<br />
これをどう使うのかというとActionScriptで使用しますのでタイムラインアクションを出してみましょう。<br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/95fb5c39a6463517bfe3b00da0487388.png" title="タイムラインアクション"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/95fb5c39a6463517bfe3b00da0487388-294x300.png" alt="タイムラインアクション" title="タイムラインアクション" width="294" height="300" class="alignnone size-medium wp-image-1046" /></a><br />
そこでクリップボードのXMLを変数に入れます。</p>
<pre class="brush: as3">
var motion_xml:XML = <Motion duration="30" xmlns="fl.motion.*" xmlns:geom="flash.geom.*" xmlns:filters="flash.filters.*">
	<source>
		<Source frameRate="24" x="97" y="178" scaleX="1" scaleY="1" rotation="0" elementType="movie clip" instanceName="kao_5" symbolName="kao">
			<dimensions>
				<geom:Rectangle left="0" top="0" width="80" height="80"/>
			</dimensions>
<transformationPoint>
				<geom:Point x="0.5" y="0.5"/>
			</transformationPoint>
		</Source>
	</source>

	<Keyframe index="0" tweenSnap="true">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>

	<Keyframe index="7" tweenSnap="true" x="88.80000000000001">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>

	<Keyframe index="15" tweenSnap="true" x="190.3">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>

	<Keyframe index="25" tweenSnap="true" x="317.2">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>

	<Keyframe index="29" tweenSnap="true" x="367.95">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>
</Motion>
</pre>
<p>ぞわーっとコードが増えましたが、XMLコピペしたぶん長いだけなので、実質は<br />
var motion_xml:XML =<br />
て書いてペーストしただけです。<br />
さらに続けて</p>
<pre class="brush: as3">
var motion:Animator = new Animator(motion_xml, icon);
motion.play();
</pre>
<p>こう書き足していきます。<br />
Animatorコンストラクタの引数にそれぞれ、XML、動かしたいインスタンスのインスタンス名を入れます。<br />
CS5などのアクションパネルでコード補完が効いていれば必要なimportも自動で行ってくれるはずなので、最終的にはこうなっているはずです。</p>
<pre class="brush: as3">
import fl.motion.Animator;

var motion_xml:XML = <Motion duration="30" xmlns="fl.motion.*" xmlns:geom="flash.geom.*" xmlns:filters="flash.filters.*">
	<source>
		<Source frameRate="24" x="97" y="178" scaleX="1" scaleY="1" rotation="0" elementType="movie clip" instanceName="kao_5" symbolName="kao">
			<dimensions>
				<geom:Rectangle left="0" top="0" width="80" height="80"/>
			</dimensions>
<transformationPoint>
				<geom:Point x="0.5" y="0.5"/>
			</transformationPoint>
		</Source>
	</source>

	<Keyframe index="0" tweenSnap="true">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>

	<Keyframe index="7" tweenSnap="true" x="88.80000000000001">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>

	<Keyframe index="15" tweenSnap="true" x="190.3">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>

	<Keyframe index="25" tweenSnap="true" x="317.2">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>

	<Keyframe index="29" tweenSnap="true" x="367.95">
		<tweens>
			<SimpleEase ease="0"/>
		</tweens>
	</Keyframe>
</Motion>

var motion:Animator = new Animator(motion_xml, icon);
motion.play();
</pre>
<p>ちなみにモーションとは関係ないですが、変数にXMLを入れる場合は「ダブルクオート（”）」などの引用符は付けないです（ASが内部にパーサーを備えているのでXMLの開始タグと終了タグを理解するため）。</p>
<h3>まとめ</h3>
<p>モーションの再利用について今回改めて調べてみて、いろいろな方法があることがわかりました。<br />
他にも「XMLとして保存、読み込み」とか「モーションを特殊ペースト」など僕がまだまだわからない方法もありますが、うまいこと使いどころを考えていくとなかなかに便利なのかなという気もします。</p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/1019/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/1019" />
	</item>
		<item>
		<title>&#8220;Hello World!&#8221;;//出産のお知らせ</title>
		<link>http://utweb.jp/blog/archives/1013</link>
		<comments>http://utweb.jp/blog/archives/1013#comments</comments>
		<pubDate>Tue, 14 Jun 2011 23:44:25 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=1013</guid>
		<description><![CDATA[正宗です。
このブログはたぶん今までは仕事がらみの話しか書いたこと無いですが、夫婦で自営業として受託案件を請け負っている以上、お仕事でも多くの方のご協力を頂きましたのでここにご報告しておこうと思いました。
宇都宮家に第一 [...]]]></description>
			<content:encoded><![CDATA[<p>正宗です。<br />
このブログはたぶん今までは仕事がらみの話しか書いたこと無いですが、夫婦で自営業として受託案件を請け負っている以上、お仕事でも多くの方のご協力を頂きましたのでここにご報告しておこうと思いました。</p>
<p>宇都宮家に第一子が誕生しました。<br />
3274g 女の子　母子共に健康です！<br />
<span id="more-1013"></span><br />
<a href="http://utweb.jp/blog/wp-content/uploads/2011/06/37e3808047553cedb34daa9b1d7ab2a3.jpg" title="子"><img src="http://utweb.jp/blog/wp-content/uploads/2011/06/37e3808047553cedb34daa9b1d7ab2a3-300x300.jpg" alt="子" title="子" width="300" height="300" class="alignnone size-medium wp-image-1014" /></a><br />
まだまだこれから先の方が長いですが、とりあえず出産に至るまでにも我々は多くのことを学びました。</p>
<p>この子が産まれることは完全に我が家の都合なのに、本当に多くの方々に支えて頂きました！<br />
直接に出産まで専門的にサポートして頂いた産院先生や助産婦さんから、仕事のスケジュールをわざわざ都合つけて頂いたお取引皆様方、応援やお祝いのメッセージ頂いた方々、親戚家族一同、その他諸々、皆様方のお力添えのたまものであり私たちはそうとうな幸せ者です。</p>
<p>万感の思いもあり、これからもばりばり働いてこの子を社会の役に立つ立派な大人に育てることが恩返しと感じていますが、まずは当事業所のスタッフでもある母体の回復に努め、その間幸せに浸っておこうかと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/1013/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/1013" />
	</item>
		<item>
		<title>Flashで仮想現実を試してみる</title>
		<link>http://utweb.jp/blog/archives/995</link>
		<comments>http://utweb.jp/blog/archives/995#comments</comments>
		<pubDate>Sun, 01 May 2011 13:15:00 +0000</pubDate>
		<dc:creator>正宗</dc:creator>
				<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://utweb.jp/blog/?p=995</guid>
		<description><![CDATA[21世紀もはや10分の一が過ぎ、世の中では拡張現実（AR）の研究や期待が高まっています。
そんな中で忘れ去られた感もある仮想現実（VR）の世界。
そう、かつてシュワちゃんとかが宮沢りえとTVCMに出ていたような時代にヴァ [...]]]></description>
			<content:encoded><![CDATA[<p>21世紀もはや10分の一が過ぎ、世の中では拡張現実（AR）の研究や期待が高まっています。<br />
そんな中で忘れ去られた感もある仮想現実（VR）の世界。<br />
そう、かつてシュワちゃんとかが宮沢りえとTVCMに出ていたような時代にヴァーチャルリアリティと呼ばれもてはやされたあの技術。<br />
そんな技術をいまさらながら試してみました、昭和の男、正宗です。</p>
<p>具体的には、WEBカメラをつなげていろいろ顔を動かしてみると中の3D空間も連動して動くというような奴です。ニンテンドーDSのアッタコレダっていうゲームをヒントに作ってみました。<br />
さっそくみてみましょう。<br />
（要FlashPlayer10）<br />
<span id="more-995"></span></p>
<div style="width:400px;height:300px;"><embed width="400" height="300" menu="false" loop="true" play="true" scale="showall" src="/samples/kao2/index.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></embed></div>
<p>モデルは毎度おなじみの、みんなの人気者愛媛県西予市<a href="http://www.mikame.net/j/s_topic/20070731.php" target="_blank">げんき</a>君です。<br />
やってることは、顔認識を使ってWEBカメラから顔の位置を検出して、その位置を元に3Dのカメラを動かしてるだけです。<br />
顔認識はライブラリを使っているのですが、使っているライブラリが今現在公開停止しているのか、DLできないようになっているので紹介していいものかどうか悩みます。</p>
<blockquote><p>2011/08/26追記：今みると公開されているようです！<br />
<a href="http://www.libspark.org/wiki/mash/Marilena" target="_blank">http://www.libspark.org/wiki/mash/Marilena</a></p></blockquote>
<p>いちおうソースの説明はしてみたいと思います。</p>
<p>ソースの書き方はとても汚く、またとっちらかってるのでお見せするのはとても恥ずかしいんですが、何かの参考になれば嬉しいです。<br />
<a href="http://utweb.jp/samples/kao2/virtual_ar.zip">ソースコードのDLはこちら</a><br />
別途</p>
<ul>
<li>Progression4</li>
<li>Papervision3D</li>
<li>Marilena</li>
</ul>
<p>が必要です。</p>
<h4>tools.Detecto</h4>
<p>実際に顔認識を行っているクラスは「tools.Detector」クラスになります。<br />
顔認識はとても重い処理なので、なるべく軽くなるように工夫しています。</p>
<pre class="brush: as3">
private function _onTimerHandler(event:TimerEvent):void
{
	_prevTime = getTimer();
	var video:Video = _tool.video;
	_bitmapData.draw(video, _mat);
	_detector.detect(new Bitmap(_bitmapData));
}
</pre>
<p>タイマーイベントを駆動して、顔認識を開始するようにしています。<br />
カメラ映像は一度Bitmapにする必要があるんですが、ある程度縮小することによって顔認識も軽くするようにしています。</p>
<pre class="brush: as3">
private function _onDetectionCompleteHandler(event:ObjectDetectorEvent):void
{
	if(event.rects.length > 0){
		_rect = event.rects[0] as Rectangle;
	}
	_timer.reset();
	_timer.start();
	dispatchEvent(new Event(RECTANGLE_UPDATE));
}
</pre>
<p>顔認識が完了するともう一度タイマーイベントを駆動して次の顔認識を始めるようにしています。<br />
Event.ENTER_FRAMEにしなかったのは、顔認識にかかった時間を計測して、もし遅れるようであれば顔認識の更新の間隔を遅らせるなどの処理をゆくゆくははさみたかったからです。</p>
<h4>pages.TopPage</h4>
<p>3Dの描写は直接「pages.TopPage」で行っています。<br />
顔認識が完了する度に、顔の位置を検出してカメラをそこに持って行っています。</p>
<pre class="brush: as3">
private function _detectorUpdateHandler(e:Event):void
{
	var rect:Rectangle = _detector.rect;
	if(!(!rect)){
		var rX:Number = (rect.x / VideocameraTool.VIDEO_SCALE) - ((_tool.video.width - (rect.width / VideocameraTool.VIDEO_SCALE)) * 0.5);
		var rY:Number = (rect.y / VideocameraTool.VIDEO_SCALE) - ((_tool.video.height - (rect.height / VideocameraTool.VIDEO_SCALE)) * 0.5);
		var rZ:Number = (rect.width - _RECT_MIN) * _renge;
		var cX:Number = rX * _viewScaleX * _SCALE_VIEW;
		var cY:Number = -rY * _viewScaleY * _SCALE_VIEW;

		_view.camera.zoom = rZ + 40;

		var matX:Matrix3D = Matrix3D.rotationMatrix(0, 1, 0, cX * _PI);
		var matY:Matrix3D = Matrix3D.rotationMatrix(1, 0, 0, cY * _PI);
		var mat:Matrix3D = Matrix3D.multiply(matX, matY);
		_view.camera.transform = Matrix3D.multiply(mat, _cameraMatrix);

	}
}
</pre>
<p>なんかごそごそとややこしいことをしてそうに見えますが、僕のコードの書き方が下手なだけで、実際には顔認識の位置をカメラの位置に変換しているだけです。<br />
実は今回のソースで一番苦労したのは、<br />
Matrix3D.rotationMatrix<br />
で、カメラをX方向に何度、Y方向に何度動かしたときのXYZ座標への持って行き方が一番苦心しました。<br />
Matrix3D.rotationMatrixがそれらしい処理を行ってくれそうなのはわかったんですが、引数が謎すぎるのと、X方向、Y方向、デフォルトのカメラの位置、それぞれ3つの行列を合成させるという答えに行き着くまでが、一番時間がかかりましたｗ</p>
<h4>まとめ</h4>
<p>どうでしょうか。<br />
現実的な速度で動作させるために顔認識の精度を落としているのですが、これが将来的にもっと高速になればなかなか面白いことが出来るのではないでしょうか。<br />
個人的には顔の位置をカメラとリンクさせるだけ、というアイデアの簡潔さがとても気に入っています。</p>
]]></content:encoded>
			<wfw:commentRss>http://utweb.jp/blog/archives/995/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<xhtml:link rel="alternate" media="handheld" type="text/html" href="http://utweb.jp/blog/archives/995" />
	</item>
	</channel>
</rss>

