blocco blog

blocco blog

ブロッコ・デリの種々雑多な調子。

iPhoneでFlashを動かそう

2008-10-02(Thu) 16:37

投稿者: kisocci

FPS2008でご紹介したネタをもう少し細かくご紹介します。

Question. iPhoneにFlashPlayerはいまだ搭載されず残念ですが、知恵をしぼってiPhone「で」Flash「を」動かしてみたいと思います。

Answer. Papervision3Dで作ったiPhoneのFlashを実機iPhoneで動かしてみます。



iPhoneFlash関係図iPhoneFlashの関係図です。

■ iPhoneネイティブアプリ作り編

NDA

iPhone DeveloperのNDAに抵触する可能性がありそうなのであまりお話できません。レジストレーションしますと、サンプルプログラム等が見られます。加速度センサーのサンプルをもとに、x,y,zの値をXMLSocket形式のテキストでsocketに送出するようプログラムしましょう。socket部分は一般的なbds socketの実装で対応できます。
ここばかりはこれくらい。

■ Swift3D作り編

a.Swift3D ver5で直方体(「ボックス作成」)等からiPhoneの筐体を作ります。

  お好みでベベルやテクスチャマップをしてください。

ポイント:マテリアルの名称やテクスチャの名称に日本語が含まれていると、Papervision3Dで表示されなくなりますので注意。名称を変更しておきましょう。
例:「ER-フラット-03」を「ER-Flat-03」に。

   

b. 完成したモデルを、Papervision3Dで扱えるdae形式ファイルとして書き出します。

  Swift3D「ファイル」メニューの「シーンをPapervision3Dへとエクスポート…」を選択します。

ポイント:エクスポートに失敗するときがあります。Swift3Dを一度終了し、起動しなおして、あらためてt3dファイルを開き、(他の操作をせずに)続けてエクスポートする、のが確実なようです。

Flash作り編

c. ActionScript3.0でPapervision3Dを操ります。

Swift3Dよりエクスポートしたdaeファイルは次のようにしてモデルとして読み込みます。Papervision3Dの基礎はF-siteさんなどをご参考いただければ。
  
  
(要所抜粋)

//Papervision3Dのお約束。Scene3Dをつくります。
this.container = new Sprite();
addChild( this.container );
this.scene = new Scene3D( this.container );

//マテリアル定義にあらためて色を指定しています。     
var myMaterialsList:MaterialsList = new MaterialsList();
myMaterialsList:MaterialsList.addMaterial ( new ColorMaterial (
                  0xffffff, 100 ), "ER_flatwhite");
myMaterialsList:MaterialsList.addMaterial ( new ColorMaterial (
                  0x000000, 100 ), "ER_blackmirror");
myMaterialsList:MaterialsList.addMaterial ( new ColorMaterial (
                  0x5B5B5B, 100 ), "ER_greymirror");

//iPhone.daeを読み込みます。
mCollada = new Collada("iPhone.dae", myMaterialsList:MaterialsList, 6);

//sceneに配置します。
scene.addChild( mCollada, "iphone" );
d. XMLを受け取る部分はXMLSocketとEventListenerを利用して作ります。

  (要所抜粋)

//ソケットを開きます
private function openSocket():void {
	socket = new XMLSocket();
	configureListeners(socket);
	socket.connect("192.168.0.2", 15000);
}

//ソケットのイベントリスナーを定義します。
private function configureListeners(dispatcher:IEventDispatcher):void {
	dispatcher.addEventListener(Event.CLOSE, closeHandler);
	dispatcher.addEventListener(Event.CONNECT, connectHandler);
	dispatcher.addEventListener(DataEvent.DATA, dataHandler);
	dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
	dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
	dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
}

//XMLSocketの受信イベント(DataEvent.DATA)ハンドラ
//XMLを解析し、accX,accY,accZに移動平均値を格納します。
private function dataHandler(event:DataEvent):void { 
	var i;
   //移動平均のサンプル個数
	var movingAveBufSize = 30;

	//XMLオブジェクトの生成
	rxml = new XML(event.data);

	//X,Y,Z値のとりだし小数第二位でまるめています。
	var x0 = Math.round(parseFloat(rxml.attribute("x"))*100)/100
	var y0 = Math.round(parseFloat(rxml.attribute("y"))*100)/100
	var z0 = Math.round(parseFloat(rxml.attribute("z"))*100)/100

	//1G以上の発生は無視します。
	if (Math.abs(x0)>1 || Math.abs(y0)>1 ||Math.abs(z0)>1 ) {
		return;
	}

	//移動平均用バッファに追加します
	accx_buf.push(x0);
	accy_buf.push(y0);
	accz_buf.push(z0);

	//バッファサイズを超えたらバッファの最初(古いほう)から削除し、
	//常にmovingAveBufSize個になるように。
	if (accx_buf.length>movingAveBufSize) {
		accx_buf.shift();
	}
	if (accy_buf.length>movingAveBufSize) {
		accy_buf.shift();
	}
	if (accz_buf.length>movingAveBufSize) {
		accz_buf.shift();
	}

	//移動平均値を求めます。
	var ax = 0;
	for(i=0; i < accx_buf .length; i++) {
		ax += accx_buf[i];
	}
	accX = ax/accx_buf.length;

	var ay = 0;
	for(i=0; i < accy_buf.length; i++) {
		ay += accy_buf[i];
	}
	accY = ay/accy_buf.length;

	var az = 0;
	for(i=0; i < accz_buf.length; i++) {
		az += accz_buf[i];
	}
	accZ = az/accz_buf.length;
}
e. iPhoneモデルの動作はENTER_FRAMEで常に描画していきます。
	...
	this.addEventListener( Event.ENTER_FRAME, loop3D );
	...

private function loop3D( event :Event ):void {
	camerar += 0.02; //カメラを常に水平方向に回転させています
	camera.x = 3000*Math.sin(camerar);
	camera.z = 3000*Math.cos(camerar);

	if( iphone )
	{
		//iphoneの傾きをアップデートします
		updateObject( iphone );
	}
	//レンダリングします
	this.scene.renderCamera( camera );
}
f. iphoneの傾きのアップデート(=updateObject()の中身。loop3Dより毎度よびだされます)

  XML受信によって(+移動平均計算によって)常に更新されているaccX,accY,accZの値をもとに、傾きを計算します。角度を求める計算にはatan()を使います。

  iphoneが正面に向かって倒れる角度(rotationX)は、ラフに言えば
iphone.rotationX = Math.atan(accY/accZ)*180/Math.PI;
  とあらわせます。

iPhoneを液晶面を手前にしてたてたとき、加速度センサーの軸は左右がX(右が正)、上下がY(上が正)、前後がZ(手前が正)となります。

実際には座標系(回転の原点(0度の位置))を調整して、現物の傾きとあわせています。

if (accZ>0) {
	iphone.rotationX = 90 - Math.atan(accY/accZ)*180/Math.PI ;
} else {
	iphone.rotationX = 270 - Math.atan(accY/accZ)*180/Math.PI ;
}

if (accY>0) {
	iphone.rotationZ =  Math.atan(accX/accY)*180/Math.PI;
} else {
	iphone.rotationZ =  (-1)* Math.atan(accX/accY)*180/Math.PI;
}

■ 通信補足編

socket serverの準備

XMLSocketの中継のため、SocketServerが必要です。
ActionScript 3.0メモ
を参考にブロードキャストするだけでよいSocketServerを起動させておきます。
上記サイトを参考にするならば、ChatServer.javaとChatServerThread.javaが必要です。

crossdomain対策

FlashPlayer9のSocketセキュリティポリシー変更に対応するために、<policy -file-request>に
対処するサーバーをたてます。以下のruby版がよいでしょう。
古橋貞之の日記

trackback URL:
http://www.blocco-deli.co.jp/blog/2008/10/02/fps2008-1/trackback/

comment/trackback(6)

2008-10-21(,2,) 19:03 knlight

Hi, I’m working on how to send information from iphone to flash using xmlsocket. may you help me?

Here’s my email: z.knlight@gmail.com

Thanks a lot!

2008-10-21(,2,) 23:08 kisocci

Hi, knight

Thank you for reading our blog entry.

It’s my pleasure for your help.
Please ask your question feel free.

If you need, I’ll show you a socket source code
written in objective-c. :)

Takashi Kiso

2008-10-22(,3,) 12:56 knlight

Hi,Takashi Kiso

I try to send message to falsh using socket,but the flash client can’t read the message using xmlsocket.

I guess maybe it’s my iphone client problem.

So I really prefer the socket source code written in objetive-c.

Thanks a lot.

2008-10-23(,4,) 00:07 kisocci

OK. I’ll show you the source code via e-mail.
just moment please :)

2008-10-23(,4,) 12:37 knlight

ok~thx~ :)

2009-03-18(,3,) 02:20 nunugera

Hi…I am doing a work very similar to yours…I am doing an 3d view for an object in flash and paper vision and i would like to know how can i do it…
?the program to install in the iphone?if there is any program to instal in pc or mac…I am already registered in iphone devcenter…Hope you can help me…thank you very much…

画面トップへ