<?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/"
	>

<channel>
	<title>Takepepe.com &#187; Flash</title>
	<atom:link href="https://takepepe.com/category/flash/feed/" rel="self" type="application/rss+xml" />
	<link>https://takepepe.com</link>
	<description>Designer::develop</description>
	<lastBuildDate>Sun, 16 Jun 2013 15:40:24 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>LeapMotion #001 Starling</title>
		<link>https://takepepe.com/leapmotion-001-starling/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=leapmotion-001-starling</link>
		<comments>https://takepepe.com/leapmotion-001-starling/#comments</comments>
		<pubDate>Mon, 06 May 2013 11:50:42 +0000</pubDate>
		<dc:creator>Takepepe</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[LeapMotion]]></category>
		<category><![CDATA[Starling]]></category>

		<guid isPermaLink="false">http://takepepe.com/?p=426</guid>
		<description><![CDATA[LeapMotion #001 Starling from Takepepe on Vimeo. １ヶ月ぶりの [...]]]></description>
				<content:encoded><![CDATA[<p><iframe src="http://player.vimeo.com/video/65551480" width="720" height="405" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
<p><a href="http://vimeo.com/65551480">LeapMotion #001 Starling</a> from <a href="http://vimeo.com/user16458913">Takepepe</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<p>１ヶ月ぶりの投稿です。GW最終日、皆様いかがお過ごしですか？<br />
今回の投稿は、個人的に今年最も気になるガジェット「LeapMotion」についてです。</p>
<h6><a href="https://www.leapmotion.com/" target="_blank">・Leap Motion</a></h6>
<p><img src="http://takepepe.com/wp-content/uploads/2013/05/leap_logo.png" /></p>
<p>LeapMotionは端末の上1m四方空間内で、1ミリ単位で指やツール（ペン等）を検知するセンサーです。<br />
また、SDKレベルで数種類のジェスチャーを認識します。</p>
<p>つい先日、プレオーダーした人への発送延期がアナウンスされたばかりですが、<br />
自分は3月末にプレオーダー、デベロッパー登録したところ、2週間ほどで手元に届きました。<br />
発送延期の理由としては、完璧な状態として世に送り出したい、というような内容でした。<br />
7月22日が発送予定日とされていますが、実際どうなるかはまだわかりませんね。</p>
<p>まだ日本語のリソースが少ない状態ですので、コード解説にはいる前に<br />
DeveloperPortalの概要を写したものを交えて、簡単に解説したいと思います。</p>
<h2>Frame</h2>
<p>LeapMotionで値を取得するために使用するFrameオブジェクトの中には以下のものが含まれます。</p>
<h6>・Lists of tracking data</h6>
<div class="gray-rect">
Hands — すべての手<br />
Pointables — Pointableオブジェクトとして、すべての指とツール<br />
Fingers — すべての指<br />
Tools — すべてのツール<br />
Gestures — 開始、更新、終了のハンドラーを含むすべてのジェスチャー</div>
<h6>・Frame motion</h6>
<div class="gray-rect">
Rotation Axis — 回転軸を表現する方向ベクトル。<br />
Rotation Angle — 回転軸(右手の法則を使用して)のまわりで右回りの回転角。<br />
Rotation Matrix — 回転を表現するtransformマトリックス。<br />
Scale Factor — 拡大縮小を表現するファクター。<br />
Translation — 直線運動を表現するベクトル。
</div>
<h2>Hand model</h2>
<p>手について様々な情報を提供します。2本の手を認識しますが、右手左手の識別はしていません。</p>
<h6>・Hand attributes</h6>
<div class="gray-rect">
Palm Position — Leapの起点から計測した手のひら中心座標<br />
Palm Velocity — 秒速ミリメートル単位の、手のひらの移動速度<br />
Palm Normal —  手のひらの中心から、下方へ指す垂直方向のベクトル<br />
Direction — 手のひらの中心から、指へ向かうベクトル。<br />
Sphere Center — 手の屈曲に適当な球体の中心。(手でボールを持っているような感じ)<br />
Sphere Radius — 手の屈曲に適当な球体の半径。半径は手の形とともに変化します。
</div>
<h6>・Hand motion</h6>
<div class="gray-rect">
Rotation Axis — 回転軸を表現する方向ベクトル。<br />
Rotation Angle — 回転軸(右手の法則を使用して)のまわりで右回りの回転角。<br />
Rotation Matrix —回転を表現するtransformマトリックス。<br />
Scale Factor — 拡大縮小を表現するファクター。<br />
Translation — 直線運動を表現するベクトル。
</div>
<h6>・Finger and Tool lists</h6>
<p>検知した手に属する、指やツールの情報を取得できます。</p>
<div class="gray-rect">
Pointables — Pointableオブジェクトとして、すべての指とツール<br />
Fingers — すべての指<br />
Tools — すべてのツール
</div>
<h2>Finger and Tool models</h2>
<p>Leapはその視界内の指およびツールの両方を検知するおよび追跡します。</p>
<div class="gray-rect">
Length — オブジェクト(手から先端に及ぶ)の可視部の長さ。<br />
Width — オブジェクトの可視部の平均幅。<br />
Direction — オブジェクト(つまり基礎から先端まで)と同じ方角に指すユニット方向ベクトル。<br />
Tip Position — Leapの起点から計測した指先の座標<br />
Tip Velocity — 秒速ミリメートル単位の、指先の移動速度
</div>
<h2>Gestures</h2>
<p>Leapは特定の移動パターンをGesturesとして認識します。</p>
<div class="gray-rect">
Circle — 円をトレースする単一の指。<br />
Swipe — 手の直線運動。<br />
Key Tap — キーボード・キーを軽く打つかのような指の動作。<br />
Screen Tap — コンピューター・スクリーンを軽く打つかのような指の動作。
</div>
<h6>開発環境について</h6>
<p>現在サポートされている言語は、C++、C#、Objective-C、Java、Python、JavaScriptになります。<br />
DevelperPortalでは前述の概要の他に、各フレームワークに対応したライブラリの配布、<br />
ガイドライン、コミュニティ、アプリストア概要などが掲載されています。<br />
Leapに興味があるかたは是非覗いてみてください。</p>
<h6><a href="https://developer.leapmotion.com/documentation/guide/Leap_Overview">・Leap Motion Developer Portal</a></h6>
<h2>LeapMotion × Adobe AIR Starling</h2>
<p>
今回作成したデモについての解説です。<br />
AdobeAIRでStarlingのParticleSystemを使用して作成しています。
</p>
<h6><a href="http://gamua.com/starling/" target="_blank">・Starling Framework</a><br />
<a href="https://github.com/PrimaryFeather/Starling-Extension-Particle-System" target="_blank">・Starling-Extension-Particle-System</a></h6>
<p>
StarlingはStage3Dを使用しているのでapp.xmlに以下の設定を忘れずにしましょう。
</p>
<div class="gray-rect">
&lt;renderMode&gt;direct&lt;/renderMode&gt;<br />
&lt;depthAndStencil&gt;false&lt;/depthAndStencil&gt;
</div>
<p>
LeapをActionScriptで使用するために、以下のライブラリと付属のC++SDKをラップしているANEを使用します。<br />
導入方法については、下記ページの下部に書いてあるので、それぞれ開発環境にあったものを選んでください。<br />
自分はFlashBuilder4.7でした。
</p>
<h6><a href="https://github.com/logotype/LeapMotionAS3" target="_blank">・LeapMotionAS3</a></h6>
<p>
Starlingを使用したパーティクルのデモは<a href="http://clockmaker.jp/blog/" target="_blank">Clockmakerさん</a>や<a href="http://www.project-nya.jp/" target="_blank">にゃあプロジェクトさん</a>が充実していますので、<br />
そちらを参考にさせていただきました。
</p>
<h3>FL001.as</h3>
<pre class="brush: as3; title: ; notranslate">
package {
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageDisplayState;
	import flash.display.StageScaleMode;
	import flash.events.KeyboardEvent;
	import starling.core.Starling;
	
	[SWF(backgroundColor=&quot;#00164a&quot;, width=&quot;1440&quot;, height=&quot;900&quot;, frameRate=&quot;60&quot;)]
	
	public class FL001 extends Sprite {
		
		private var starling:Starling;
		
		public function FL001() {
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
			
			starling = new Starling(MainView, stage);
			starling.start();
			
		}
		
		private function onKeyDown(e:KeyboardEvent):void {
			
			if(stage.displayState == StageDisplayState.NORMAL){
				stage.displayState = StageDisplayState.FULL_SCREEN;
			} else {
				stage.displayState = StageDisplayState.NORMAL
			}
			
		}
		
		
	}
}

</pre>
<h3>MainView.as</h3>
<pre class="brush: as3; title: ; notranslate">
package {
	
	import flash.geom.Rectangle;
	import starling.core.Starling;
	import starling.display.Sprite;
	import starling.events.Event;
	import starling.events.ResizeEvent;
	import starling.extensions.ParticleDesignerPS;
	import starling.textures.Texture;
	import com.leapmotion.leap.LeapMotion;
	import com.leapmotion.leap.Pointable;
	import com.leapmotion.leap.events.LeapEvent;
	
	internal class MainView extends Sprite { 
		
		// 事前に「online particle editor」で.pexファイルとtexture.pngを用意しておきます
		// http://onebyonedesign.com/flash/particleeditor/
		
		[Embed(source = &quot;assets/particle.pex&quot;, mimeType = &quot;application/octet-stream&quot;)]
		private static var ParticleData:Class;
		
		[Embed(source = &quot;assets/texture.png&quot;)]
		private static var ParticleImage:Class;
		
		private var particles:Vector.&lt;ParticleDesignerPS&gt;;		
		private var count:int = 10;
		private var leap:LeapMotion;
		
		public function MainView() {
			addEventListener(Event.ADDED_TO_STAGE, onAddStage);
		}
		
		private function onAddStage(e:Event):void {
			
			setParticles();
			leap = new LeapMotion();
			leap.controller.addEventListener( LeapEvent.LEAPMOTION_FRAME, onLeapFrame );
			stage.addEventListener(ResizeEvent.RESIZE, onResizeStage);
			
		}
		
		private function setParticles():void{
			
			particles = new Vector.&lt;ParticleDesignerPS&gt;(10);
			for(var i:int = 0; i&lt;count ; i++){
				particles[i] = new ParticleDesignerPS( XML(new ParticleData()), Texture.fromBitmap(new ParticleImage()));
				particles[i].startSize = 100;
				particles[i].endSize = 100;
				particles[i].speed = 0;
				particles[i].start();
				Starling.juggler.add(particles[i]);
				addChild(particles[i]);
			}
			
		}
		
		private function onResizeStage(e:ResizeEvent):void {
			
			Starling.current.viewPort = new Rectangle(0, 0, e.width, e.height);
			stage.stageWidth = e.width;
			stage.stageHeight = e.height;
			
		}
		
		private function onLeapFrame(e:LeapEvent):void {
			
			var max:int = e.frame.pointables.length;
			for(var i:int = 0; i&lt;count ; i++){
				if( i &lt; max ){
					var pointable:Pointable = e.frame.pointables[i];
					particles[i].emitterX = (pointable.tipPosition.x)*3+stage.stageWidth/2;
					particles[i].emitterY = (pointable.tipPosition.y)*-3+stage.stageHeight;
					particles[i].gravityX = pointable.tipVelocity.x*-5;
					particles[i].gravityY = pointable.tipVelocity.y*5;
					particles[i].maxNumParticles = 50;
				}else{
					particles[i].maxNumParticles = 1;
				}
			}
			
		}
		
	}
}

</pre>
<p>１ヶ月いじった上で得た感想（というかぶちあたっている壁）です。</p>
<ol>
<li>指がLeapに向かって垂直に重なると検知できない。</li>
<li>細かなUI操作に向いていない</li>
<li>ジェスチャーはそのままでは利用しづらい</li>
</ol>
<p>
あくまで、現状公開されているSDKとライブラリを使用した上での感想です。<br />
概要を読む限りではワクワクするばかりですが、ちゃんとアプリケーションに落とし込むためには<br />
上記の問題をカバーしたフレームワークが必要だなと思いました。
</p>
<p>
今回の投稿はさらっと紹介しただけになってしまったので、<br />
次回はちょっとしたフレームワークと何か面白いネタで投稿できればいいなー。</p>
]]></content:encoded>
			<wfw:commentRss>https://takepepe.com/leapmotion-001-starling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash x iOS #001 Away3D</title>
		<link>https://takepepe.com/flash-x-ios-001-away3d/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=flash-x-ios-001-away3d</link>
		<comments>https://takepepe.com/flash-x-ios-001-away3d/#comments</comments>
		<pubDate>Wed, 27 Mar 2013 16:21:20 +0000</pubDate>
		<dc:creator>Takepepe</dc:creator>
				<category><![CDATA[Flash]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Away3D]]></category>
		<category><![CDATA[frocessing]]></category>
		<category><![CDATA[OSC]]></category>
		<category><![CDATA[tuio]]></category>

		<guid isPermaLink="false">http://takepepe.com/?p=390</guid>
		<description><![CDATA[Flash x iOS #001 Away3D from Takepepe on Vimeo. 久々の投稿です [...]]]></description>
				<content:encoded><![CDATA[<p><iframe src="http://player.vimeo.com/video/62793330" width="720" height="405" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
<p><a href="http://vimeo.com/62793330">Flash x iOS #001 Away3D</a> from <a href="http://vimeo.com/user16458913">Takepepe</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<p>久々の投稿です。<br />
桜が満開ですね！今年は多忙につき花見はお預けな感じです。</p>
<p>今回はAway3Dを使ったデスクトップAIRアプリです。<br />
OSC通信でiPadから送られて来たタッチ座標と端末の傾きで、指の位置を3D空間に変換しています。<br />
レインボーな箱がウネウネとしています。特に意味はありません。</p>
<p>iPadからOSC送信するアプリはopenFrameWorksで作ったものです。<br />
早速見て行きましょう。</p>
<ol>
<li>iPadからOSC送信</li>
<li>FlashでOSC受信</li>
<li>受信した値から指の位置をシュミレート</li>
<li>レインボーな箱をウネウネ</li>
</ol>
<h2>1.iPadからOSC送信</h2>
<p>
iPadからOSC送信します。<br />
いつもの様にemptyExampleをコピペしたら、「iOS Application Target」の「Devices」を<br />
「iPad」か「Universal」にします。<br />
FI001::setup()で画面の向きをiPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_LEFT);<br />
にして、ホームボタンが右に来たときに左上が(0,0)になるようにします。</p>
<p>iPadでは同時に5つのタッチ座標が取得できます。<br />
5つの座標を格納できる「touchLoc」を用意し、タッチが5つに満たない場合、<br />
(-100,-100)を入れる様にしておき、常に5つ分の座標を送ります。
</p>
<p>
※Supported Intereface Orientationsを「Portrait」にしていますが、<br />
これを「LandscapeRight」にしながら、左上を(0,0)にする方法が分からず…知ってる人いたら教えてください！
</p>
<h3>FI001.cpp</h3>
<pre class="brush: cpp; title: ; notranslate">
void FI001::setup(){
    
    ofBackground(127,127,127);
    
    //iPadの向きの設定
    iPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_LEFT);
    
    //加速度センサーを有効に
	ofxAccelerometer.setup();
    
    //ofxiPhoneCoreLocationインスタンスのコンパスを有効に
    location.startHeading();
    
    //OSC設定
    sender.setup( HOST, PORT );
	receiver.setup( MYPORT );
    
    //初期設定
    for (int i=0; i&lt;5; i++) {
        touchLoc[i].set(-100, -100);
    }
    
}

//--------------------------------------------------------------
void FI001::update(){
    
    ofxOscMessage m;
    m.setAddress(&quot;/iOSOSC&quot;);
    
    //タッチ位置の格納
    for (int i=0; i&lt;5; i++) {
        m.addIntArg(touchLoc[i].x);
        m.addIntArg(touchLoc[i].y);
    }
    
    //加速度
    m.addFloatArg(ofxAccelerometer.getForce().x);
    m.addFloatArg(ofxAccelerometer.getForce().y);
    m.addFloatArg(ofxAccelerometer.getForce().z);
    
    //X軸の傾き
    m.addFloatArg(ofxAccelerometer.getOrientation().y);
    
    //Y軸の傾き（コンパスの向き）
    m.addFloatArg(location.getMagneticHeading());
    
    //Z軸の傾き
    m.addFloatArg(ofxAccelerometer.getOrientation().x);
    
    sender.sendMessage( m );
    
}
</pre>
<h2>2.FlashでOSC受信</h2>
<h3>OSC.as</h3>
<p>
FlashでOSC通信をする場合、AIRアプリに限定される様です。（UDPConnectorあたり）<br />
ライブラリはtuio-as3を使っています。</p>
<h4>tuio-as3</h4>
<p><a href="https://code.google.com/p/tuio-as3-lib/" target="_blank">https://code.google.com/p/tuio-as3-lib/</a></p>
<p>
openFrameWorksから送られて来たOSCメッセージを連想配列にまとめて<br />
メインスレッド（FI001.as）に渡します。<br />
タッチ座標(-100,-100)が送られて来た場合、非表示の真偽値をセットします。
</p>
<pre class="brush: as3; title: ; notranslate">
package {
	
	import flash.display.*;
	import flash.geom.*;
	import org.tuio.connectors.UDPConnector;
	import org.tuio.osc.IOSCListener;
	import org.tuio.osc.OSCManager;
	import org.tuio.osc.OSCMessage;
	
	public class OSC implements IOSCListener {
		
		private var delegate:FI001;
		private var fingers:Vector.&lt;Object&gt;;
		private var accelerometer:Vector.&lt;Number&gt;;
		private var orientation:Vector.&lt;Number&gt;;
		private var oscManager:OSCManager;
		
		public function OSC (_delegate:FI001) {
			
			delegate = _delegate;
			
			//タッチ情報
			fingers = new Vector.&lt;Object&gt;(5,true);
			for(var i:int = 0 ; i&lt;5 ; i++){
				fingers[i] = new Object();
			}
			
			//加速度と傾き
			accelerometer = new Vector.&lt;Number&gt;(3,true);
			orientation = new Vector.&lt;Number&gt;(3,true);
			for(var j:int = 0 ; j&lt;3 ; j++){
				accelerometer[j] = 0;
				orientation[j] = 0;
			}
			
			// OSC設定　※ UDPConnectorはAIRアプリでのみ利用出来る
			var connectorIn:UDPConnector = new UDPConnector(&quot;192.168.11.20&quot;,8000);
			var connectorOut:UDPConnector = new UDPConnector(&quot;192.168.11.18&quot;,8001,false);
			oscManager = new OSCManager(connectorIn,connectorOut,true);
			oscManager.addMsgListener (this);
			
		}

		public function acceptOSCMessage (oscmsg:OSCMessage):void {
			
			//OSCメッセージを受信したら、delegateに連想配列を渡す
			
			if(oscmsg.address == &quot;/iOSOSC&quot;) {

				//タッチ情報
				for(var i:int = 0 ; i&lt;5 ; i++){
					fingers[i].x = oscmsg.arguments[i*2];
					fingers[i].y = oscmsg.arguments[i*2+1];
					fingers[i].visible = true;
					if(fingers[i].x &lt; 0){
						fingers[i].visible = false;
					}
				}
				
				//加速度と傾き
				accelerometer[0] = oscmsg.arguments[10];
				accelerometer[1] = oscmsg.arguments[11];
				accelerometer[2] = oscmsg.arguments[12];
				orientation[0] = oscmsg.arguments[13];
				orientation[1] = oscmsg.arguments[14];
				orientation[2] = oscmsg.arguments[15];
				
				//まとめ
				var data:Object = new Object();
				data.fingers = fingers;
				data.accelerometer = accelerometer;
				data.orientation = orientation;

				delegate.onMessage (data);
				
			}
		}
		
		public function sendOSCMessage ():void { }
		public function sendOSCBundle ():void { }

	}

}
</pre>
<h2>3.受信した値から指の位置をシュミレート</h2>
<h3>FI001.as</h3>
<p>
ここからAway3Dを使ってコーディングしていきます。<br />
Stage3Dを使ったAIRアプリは「app.xml」の</p>
<p class="gray-rect">
&lt;renderMode&gt;direct&lt;/renderMode&gt;<br />
&lt;depthAndStencil&gt;true&lt;/depthAndStencil&gt;
</p>
<p>を設定し忘れる「context3Dなんて知らないよ」って怒られるので注意。<br />
ブラウザで見るswfの場合は、htmlのwmodeをdirectにしましょう。<br />
Away3Dは現状で最新の「4.1.0 Alpha」を使います。
</p>
<h5>Away3D 4.1.0 Alpha</h5>
<p><a href="http://away3d.com/download/away3d_4.1.0_alpha" target="_blank">http://away3d.com/download/away3d_4.1.0_alpha</a></p>
<pre class="brush: as3; title: ; notranslate">
package {
	
	import away3d.cameras.Camera3D;
	import away3d.containers.Scene3D;
	import away3d.containers.View3D;
	import away3d.lights.DirectionalLight;
	import away3d.materials.lightpickers.StaticLightPicker;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Vector3D;
	import flash.system.System;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	[SWF(backgroundColor=&quot;#000717&quot;, width=&quot;1024&quot;, height=&quot;768&quot;, frameRate=&quot;60&quot;)]
	
	public class FI001 extends Sprite{
		
		// OSC通信で使うインスタンス
		private var osc:OSC;
		private var tf:TextField;
		
		// Away3Dでお決まりのインスタンス
		private var view:View3D;
		private var scene:Scene3D;
		private var camera:Camera3D;
		private var light:DirectionalLight;
		private static var ZERO:Vector3D = new Vector3D(0,0,0);
		
		// Away3Dで使うインスタンス
		private var fingers:Vector.&lt;Finger&gt;;
		
		// iPadの傾きを格納する変数
		private var ox:Number = 0;
		private var oy:Number = 0;
		private var oz:Number = 0;		

		public function FI001(){
			
			// ガベージコレクション設定（以下参考）
			// http://adclounge.jp/adobe-max-2011/new-small-features-in-flash-player-11/
			System.pauseForGCIfCollectionImminent(1);
			
			// OSCメッセージを受信したらデータを渡してくれるインスタンス
			osc = new OSC(this);
			
			// Away3Dの設定
			init3D();
			
			// 3Dオブジェクトの設定
			set3D();
			
			// デバッグ用テキスト（OSC受信した値表示用）
			setText();
			
		}
		
		private function init3D():void{
			
			// Away3Dの設定
			view = new View3D();
			scene = view.scene;
			light = new DirectionalLight();
			light.direction = new Vector3D(1, -1, 1);
			light.specular = 0.1;
			light.diffuse = 0.9;
			light.ambient = 0.1;
			scene.addChild(light);
			camera = view.camera;
			camera.z = -500;
			
			addChild(view);
			
		}
		
		private function set3D():void {
			
			var lightPicker:StaticLightPicker = new StaticLightPicker([light]);
			
			// タッチ座標に応じてCubeを表示するFingerインスタンス
			fingers = new Vector.&lt;Finger&gt;(5,true);
			for (var i:int = 0; i &lt; 5; i++) {
				var finger:Finger = new Finger();
				fingers[i] = finger;
				for(var j:int = 0 ; j&lt;fingers[i].cubes.length ; j++){
					scene.addChild(fingers[i].cubes[j].mesh);
					fingers[i].setLightPicker(lightPicker);
				}
			}
			
			// アニメーションループ
			addEventListener(Event.ENTER_FRAME, update, false, 0, true);
			
		}
		
		private function setText():void{
			
			// デバッグ用テキスト（OSC受信した値表示用）
			tf = new TextField();
			tf.textColor = 0xFFFFFF;
			tf.autoSize = TextFieldAutoSize.LEFT;
			addChild(tf);
			
		}
		
		private function update(e:Event):void {
			
			// アニメーションループ
			for (var i:int = 0; i &lt; 5; i++) {
				fingers[i].update();
			}
			view.render();
			
		}
		
		
		
		public function onMessage(_data:Object):void{
			
			// ローパスフィルターを通してセンサーの傾きを格納
			ox = ox*0.9 + (_data.orientation[0]+180)*0.1;
			oy = oy*0.9 + (_data.orientation[1])*0.1;
			oz = oz*0.9 + (_data.orientation[2]+180)*0.1;
			
			// 画面の中心
			var cx:Number = -stage.width/2;
			var cy:Number = -stage.height/2;
			
			for(var i:int = 0 ; i&lt;_data.fingers.length ; i++){
				
				var fx:Number = cx+_data.fingers[i].x;
				var fy:Number = cy+_data.fingers[i].y;
				var x:Number = -fx*Math.cos((oz)*Math.PI/180);
				var y:Number = -fy*Math.sin((ox)*Math.PI/180);
				var z:Number = fy*Math.cos((ox)*Math.PI/180);-fx*Math.cos((oy)*Math.PI/180);
				
				// iPadの傾きとタッチ位置から座標を特定
				fingers[i].vec.setTo(x,y,z);
				
				// 触っていなかったら非表示
				fingers[i].setVisible(_data.fingers[i].visible);
			}
			
			setMessageTet();
			
		}
		
		private function setMessageTet():void{
			
			// デバッグ用テキスト（OSC受信した値表示用）
			var str:String = &quot;&quot;;
			for(var i:int = 0 ; i&lt;fingers.length ; i++){
				str += &quot;finger&quot;+(i+1)+&quot;X:&quot;+fingers[i].vec.x+&quot;\n&quot;;
				str += &quot;finger&quot;+(i+1)+&quot;Y:&quot;+fingers[i].vec.y+&quot;\n&quot;;
			}
			str += &quot;orientationX:&quot;+ox+&quot;\n&quot;;
			str += &quot;orientationY:&quot;+oy+&quot;\n&quot;;
			str += &quot;orientationZ:&quot;+oz+&quot;\n&quot;;
			tf.text = str;
			
		}
		
	}
}
</pre>
<h2>4.レインボーな箱をウネウネ</h2>
<p>
メインスレッドで利用しているクラスは以下の通りです。<br />
レインボー色を出すのにfrocessingを使って楽しています。
</p>
<h5>frocessing</h5>
<p><a href="http://www.libspark.org/wiki/nutsu/Frocessing" target="_blank">http://www.libspark.org/wiki/nutsu/Frocessing</a></p>
<h3>Finger.as</h3>
<pre class="brush: as3; title: ; notranslate">
package {
	
	import flash.geom.Point;
	import flash.geom.Vector3D;
	import frocessing.color.ColorHSV;
	import away3d.materials.lightpickers.StaticLightPicker;
	
	public class Finger{
		
		public var vec:Vector3D;
		public var cubes:Vector.&lt;Cube&gt;;
		private var index:int = 0;
		private static var NUM:Number = 50;
		
		public function Finger(){
			
			// 指の疑似3次元座標
			vec = new Vector3D;
			
			// ウネウネするCube達
			cubes = new Vector.&lt;Cube&gt;(NUM);
			for(var i:int = 0; i&lt;NUM ; i++){
				var color:ColorHSV = new ColorHSV(360/NUM*i,0.4);
				cubes[i] = new Cube(1,1,1,color.value);
			}
			
		}
		
		public function setLightPicker(_lp:StaticLightPicker):void{
			
			// Cube達に光源設定
			for(var i:int = 0; i&lt;NUM ; i++){
				cubes[i].setLightPicker(_lp);
			}
			
		}
		
		public function setVisible(_visible:Boolean):void{
			
			// iPadを触っていない場合非表示
			for(var i:int = 0; i&lt;NUM ; i++){
				cubes[i].mesh.visible = _visible;
			}
			
		}
		
		
		
		public function update():void{
			
			// 操作するCubeのIndex
			index++;
			if(index&gt;=NUM){
				index = 0;
			}
			
			// 順番が回って来たCubeが触ってる場所に移動する
			cubes[index].setLife(100);
			cubes[index].setVector(vec.x,vec.y,vec.z);
			
			// Cube達を更新
			for(var i:int = 0; i&lt;NUM ; i++){
				cubes[i].update();
			}
			
		}
		
	}
}
</pre>
<h3>Cube.as</h3>
<pre class="brush: as3; title: ; notranslate">
package {

	import away3d.entities.Mesh;
	import away3d.materials.ColorMaterial;
	import away3d.materials.lightpickers.StaticLightPicker;
	import away3d.primitives.CubeGeometry;
	
	public class Cube{
		
		public var mesh:Mesh;
		private var life:Number = 0;
		private var isSurvive:Boolean = false;
		
		public function Cube(_width:Number,_height:Number,_depth:Number,_color:uint){
			
			// CubeMeshの生成
			var geo:CubeGeometry = new CubeGeometry(_width,_height,_depth);
			var mat:ColorMaterial = new ColorMaterial(_color,0.8);
			mesh = new Mesh(geo,mat);
			
			// 影を落とすかどうか
			mesh.castsShadows=true;

		}
		
		public function setVector(_x:Number,_y:Number,_z:Number):void{

			mesh.x = _x;
			mesh.y = _y;
			mesh.z = _z;
			
		}
		
		public function setLightPicker(_lp:StaticLightPicker):void{
			
			mesh.material.lightPicker = _lp;
			
		}
		
		public function setLife(_life:Number):void{
			
			life = _life;
			
		}
		
		public function update():void{
			
			mesh.rotationX = Math.sin(life*Math.PI/180)*500;
			mesh.rotationY = Math.cos(life*Math.PI/180)*500;
			mesh.rotationZ = Math.cos(life*Math.PI/180)*500;
			
			var scale:Number = Math.pow(life,4)/2000000;
			mesh.scaleX = scale;
			mesh.scaleY = scale;
			mesh.scaleZ = scale;
			
			life--;
			
		}
		
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>https://takepepe.com/flash-x-ios-001-away3d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash #001 Media</title>
		<link>https://takepepe.com/flash-001/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=flash-001</link>
		<comments>https://takepepe.com/flash-001/#comments</comments>
		<pubDate>Fri, 15 Feb 2013 13:56:13 +0000</pubDate>
		<dc:creator>Takepepe</dc:creator>
				<category><![CDATA[Flash]]></category>

		<guid isPermaLink="false">http://takepepe.com/?p=195</guid>
		<description><![CDATA[flash on 2013-2-15 &#8211; wonderfl build flash online  [...]]]></description>
				<content:encoded><![CDATA[<p><script type="text/javascript" src="http://wonderfl.net/blogparts/t0eb/js"></script></p>
<p class="ttlBpWonderfl" style="width: 465px; margin: 0; text-align: right; font-size: 11px;"><a href="http://wonderfl.net/c/t0eb" title="flash on 2013-2-15">flash on 2013-2-15 &#8211; wonderfl build flash online</a></p>
<p>Takepepeはスノボが大好きです。<br />
  痛いのが嫌なので、パウダー派です。冬最高！</p>
<p>SNSなどに利用している自分のアバター画像はスノボウェアの自分…<br />
  ではなく、中身はそこら辺にあった毛布を帽子に突っ込んで撮影しましたw</p>
<p>iPhoneで撮影したら、レンズにバッチリ自分も写っていたため、Photoshopで編集することに。<br />
  静止画には風景を合成して入れていますが、今回はここにウェブカムの映像を映してそれっぽく変形させます。<br />
  ActionScriptには便利なフィルターがたくさんあるので、そいつでグニャっとね。</p>
<p>おおまかな流れは以下</p>
<ol>
<li>画像を読み込んで各レイヤーを配置</li>
<li>カメラ映像を映す</li>
<li>変形に使うフォースマップを用意</li>
<li>映写レイヤーを変形</li>
<li>ミラー反転も忘れずに</li>
</ol>
<h2>1.画像を読み込んで各レイヤーを配置</h2>
<p>swfに画像を埋め込んだり、同ドメイン内の外部画像を読み込む場合はここは飛ばしていいです。<br />
  Wonderflに投稿して自サーバーの画像を読み込む場合はクロスドメインポリシーファイルをサイトルートなどに設置する必要があります。</p>
<h5>crossdomain.xml</h5>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;cross-domain-policy&gt;
  &lt;allow-access-from domain=&quot;wonderfl.kayac.com&quot; /&gt;
  &lt;allow-access-from domain=&quot;wonderfl-swf.kayac.com&quot; /&gt;
  &lt;allow-access-from domain=&quot;*.wonderfl.net&quot; /&gt;
&lt;/cross-domain-policy&gt;
</pre>
<h5>Main.as</h5>
<pre class="brush: as3; title: ; notranslate">
public function Main() {

	// クロスドメインポリシーファイルの読み込み
	Security.loadPolicyFile( &quot;http://takepepe.com/crossdomain.xml&quot; ) ;
    
}

private function setAvator():void{

	lens = new Bitmap (lensBmd);
    addChild(lens);
    
    screenBmd = new BitmapData(465,465,true,0x00000000);
    screen = new Bitmap(screenBmd);
    screen.blendMode = &quot;overlay&quot;; //ブレンドモード設定
    addChild(screen);
    
    frame = new Bitmap (frameBmd);
    addChild(frame);
    
}
</pre>
<p>レンズ下地、映写レイヤー、フレームの順に重ねたら、映写レイヤーにはこの段階でblendModeを設定しておきます。<br />
  &#8220;overlay&#8221;で、レンズっぽくなります。</p>
<h2>2.カメラ映像を映す</h2>
<p>このVideoインスタンスはaddChildする必要はありません。<br />
  VideoとCameraのインスタンス設定は以下の箇所です。</p>
<h5>Main.as</h5>
<pre class="brush: as3; title: ; notranslate">
private function setCamera():void{

	camera = Camera.getCamera();
    camera.setMode(WIDTH,HEIGHT,30,true);
    camera.addEventListener(ActivityEvent.ACTIVITY,onActiveCamera);
    video = new Video(WIDTH,HEIGHT);
    video.attachCamera(camera);
    
}
</pre>
<h2>3.変形に使うフォースマップを用意</h2>
<p>赤ければ赤いほど、下方向にピクセルが移動する力が働いています。<br />
  インタラクションでグラデーションを動かせると、ActionScriptでしか出来ない表現ができるようになります。<br />
  Flashをクリックするとグラデーションの表示・非表示が切り替わります。<br />
  フィルターの設定は4で。</p>
<p>    <script type="text/javascript" src="http://wonderfl.net/blogparts/cP1H/js"></script></p>
<p class="ttlBpWonderfl" style="width: 465px; margin: 0; text-align: right; font-size: 11px;"><a href="http://wonderfl.net/c/cP1H" title="Flash #001 Media'">Flash #001 Media&#8217; &#8211; wonderfl build flash online</a></p>
<h2>4.映写レイヤーを変形</h2>
<p>X軸の変形は必要ないので、適当な値を入れています。</p>
<h5>Main.as</h5>
<pre class="brush: as3; title: ; notranslate">
private function update(e:Event):void{
	
    var mapPoint:Point = new Point(0, 0); 
    var componentX:uint = BitmapDataChannel.GREEN;
    var componentY:uint = BitmapDataChannel.RED;
    var forceX:Number = 0;
    var forceY:Number = 200; 
    var my_filter:DisplacementMapFilter = new DisplacementMapFilter(transformer, mapPoint, componentX, componentY, forceX, forceY, &quot;color&quot;, 0, 0);
    screen.filters = new Array(my_filter);
    
}
</pre>
<h2>5.ミラー反転も忘れずに</h2>
<p>鏡面に映っている表現なので、映写の際にMatrixで反転させます。</p>
<h5>Main.as</h5>
<pre class="brush: as3; title: ; notranslate">
private function draw(e:Event):void{
	
    var matrix:Matrix = new Matrix();
    matrix.scale(-1, 1);
    matrix.translate(screenBmd.width, 0);
    screenBmd.draw(video);
			
}
</pre>
<p>全ソースは<a href="http://wonderfl.net/c/t0eb" target="_blank">Wonderfl</a>を参照してください。<br />
  次回はWebRTCとcanvasで同様の表現に挑戦したいと思います。</p>
]]></content:encoded>
			<wfw:commentRss>https://takepepe.com/flash-001/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

 Served from: takepepe.com @ 2026-04-11 07:08:58 by W3 Total Cache -->