忍者ブログ
 >admin |  >entry |  yukku++Blog 
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

外部から読み込んだSWFの内部の変数やメソッドにアクセスしたい場合は
Loader.content を Object に代入して、その Object からアクセスする。
内部に foo = 100; がある bar.swf を Loader オブジェクトに読み込んだとして


var swfObj:object = new Object();
// すでに変数 swf には bar.swf が読み込まれているとして
swfObj = swf.content;
// 表示リストへ追加するのは Loader オブジェクト
addChild(swf);

trace(swfObj.foo) // 100

メソッドも同様に扱える。もちろん public属性である必要がある。

PR
流れとしては、URLRequestにパスをStringで渡し、URLLoaderで読み込む。
URLLoader.dataをXMLオブジェクトに渡す。
それだけでXML.hoge.hogeみたくアクセスできるとのこと。カンタン。
ホントはEvent.COMPLETEとかやったほうがいいけど省略。

// こんな感じのhoge.xmlを読み込むとする
<hogeXML>
<hoge>
<value>123456</value>
<string>HOGEHOGE</string>
</hoge>
<hoge>
<value>10101010</value>
<string>HOEHOE</string>
</hoge>
</hogeXML>


var url:URLRequest;
var loader:URLLoader;
var xml:XML;

// URLLoaderに読み込み
url = new URLRequest("hoge.xml");
loader = new URLLoader(url);

// XMLオブジェクトを作る
xml = new XML(loader.data);

// 以下のようにアクセスできる
trace(xml.hoge[0].value); // 123456
trace(xml.hoge[0].string); // HOGEHOGE
trace(xml.hoge[1].value); // 10101010
trace(xml.hoge[1].string); // HOEHOE

オブジェクトついでに頂点に関するメモも。
頂点の情報は3Dオブジェクトの geometry.vertices に配列として入っている。 したがってアクセスするには以下のようにする。

cube.geometry.vertices[0].x; // 同様に y / z も取得できる

ここで、どの頂点がどの順番で配列に入っているかが問題になる。
試行錯誤(と言っても番号と座標をいじって調べただけ)の結果、以下の図のようだ

cube_vertices

"front" から数えて "back" へ。
各メッシュの表面から見たときに、左側から上へ数え、終わったらその次の縦列へ。
基本はこんなところかな。分割数が増えたり、複雑なオブジェクトになると分からないけど。

PV3Dの使い方続き。今回はマテリアル関係。要するに色とかテクスチャね。
さて、シーンとカメラとビューとレンダラーを用意して、3D空間をレンダリングできるようにしたら、
シーンにオブジェクトを追加していこう。primitive クラスに基本モデルがあるので
とりあえず分かりやすい plane と cube のオブジェクトを出してみることに。

pv3d_test.swf

回転はRotationX / Y / Z の値をいじればいい。位置も x / y / z と分かりやすいね。
今回は plane にメッシュとワイヤーフレームに単色の色を、cube にテクスチャを張ってみた。

plane のマテリアルの設定の大雑把な方法:
ColorMaterial と WireframeMaterial を作って、 compositeMaterial に 追加する。
マテリアル情報をまとめるコンテナみたいな役割って感じ。
んで、それを plane のコンストラクタに渡してやる。これでマテリアルを設定できる。

cube のテクスチャの設定の大雑把な方法:
BitmapFileMaterial に画像を読み込む。パスを設定するだけで外部画像を読み込める優れモノ。
BitmapMaterial と BitmapAssetMaterial ってのもある。今回はBitmapFileMaterial で。
それを MaterialsList に追加する。 ココでポイント。
cube には当然6面メッシュがある。だから、どの面に貼るかを設定しなくちゃならない。
それが、cubeMat.addMaterial(texture, "all") ってやつ。
"all" は全面。それぞれ"front" "back" "left" "right" "top" "bottom" でアクセスできる。
んで、それを cube のコンストラクタに渡してやる。

色とかマテリアル張るだけでだいぶさまなってくるね。
直接 pv3d_test.swf にアクセスしないとテクスチャが出ない。クロスドメインがどーのってやつか
BitmapMaterial か BitmapAssetMaterial でやればいいんだろうけど、とりあえず保留。

package  
{
	import flash.display.Sprite;
	import flash.events.Event;
	import org.papervision3d.cameras.*;
	import org.papervision3d.materials.*;
	import org.papervision3d.materials.special.CompositeMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.primitives.*;
	import org.papervision3d.render.*;
	import org.papervision3d.scenes.*;
	import org.papervision3d.view.*;
	
	[SWF (width = "320", height = "240", frameRate = "24")]
	
	public class pv3d_test extends Sprite
	{
		// 3D空間の準備
		private var scene:Scene3D = new Scene3D();
		private var camera:Camera3D = new Camera3D(60, 5, 5000);
		private var view:Viewport3D = new Viewport3D(640, 480, true);
		private var renderer:BasicRenderEngine = new BasicRenderEngine();
		
		// plane(一枚板) と cube(立方体)
		private var plane:Plane;
		private var cube:Cube;
		
		// 色やテクスチャ
		private var color:ColorMaterial;
		private var wire:WireframeMaterial;
		private var texture:BitmapFileMaterial;
		
		// 素材のコンテナ
		private var planeMat:CompositeMaterial = new CompositeMaterial();
		private var cubeMat:MaterialsList = new MaterialsList();
		
		public function pv3d_test() 
		{
			// 素材を設定する
			color = new ColorMaterial(0xFF0000, 0.8);
			wire = new WireframeMaterial(0xFFFFFF, 80, 1);
			texture = new BitmapFileMaterial("texture.jpg", true);
			
			// 素材オブジェクトを素材コンテナに追加する
			planeMat.addMaterial(color);
			planeMat.addMaterial(wire);
			// メッシュの両面に適用
			planeMat.doubleSided = true;
			
			// 素材オブジェクトを素材コンテナに追加する
			cubeMat.addMaterial(texture, "all");
			
			// オブジェクトの生成
			plane = new Plane(planeMat, 120, 120);
			cube = new Cube(cubeMat, 120, 120, 120);
			
			// 位置調整
			plane.x -= 100;
			cube.x += 100;
			camera.z = -500;
			
			// オブジェクトを追加
			scene.addChild(plane);
			scene.addChild(cube);
			
			// 表示リストに追加とイベントリスナー登録
			stage.addChild(view);
			stage.addEventListener(Event.ENTER_FRAME, update);
		}
		
		private function update(e:Event):void
		{
			// 適当に回転とかさせる
			plane.rotationX += 0.5;
			plane.rotationY += 1;
			plane.rotationZ = mouseX / 10;
			cube.rotationX += 0.5;
			cube.rotationY += 1;
			cube.rotationZ = mouseY / 10;
			
			camera.z = mouseY * -1 / 2 - 500
			
			// レンダリング処理
			renderer.renderScene(scene, camera, view);
		}
	}
}

FlashPlayer10が出て久しいこの頃。いまさらPV3Dかよって感じだけど、
まだまだPV3は戦えるよ!ってな感じでPV3Dを使う基本的なメモ。
ダウンロードは Papervision3D から。Subversionクライアントが必要なので、
TortoiseSVN を使う。使い方はぐぐれっと。簡単で使いやすいよ。
ちなみにバージョンは2.0。1.5とはかなり書き方が変わったようなので注意。
リファレンスはこちら。Papervision3D Official Documentation

// シーン、カメラ、ビュー、レンダラーを用意
var scene:Scene3D = new Scene3D();
var camera:Camera3D = new Camera3D();
var view:Viewport3D = new Viewport3D();
var renderer:BasicRenderEngine = new BasicRenderEngine();

// 一枚の板を出す
var obj:Plane = new Plane(null, 50, 50);

// ビューを stage に表示
stage.addChild(view);

// オブジェクトを scene に追加する
scene.addChild(obj);

// シーンをカメラとビューでレンダリングする。
renderer.renderScene(scene, camera, view);

シーンにオブジェクトを追加していって、カメラでレンダリング位置を決め、
レンダラーでレンダリング。ビューでレンダリング画像を表示、って感じかな。
ちょっとづつ踏んでいけば簡単なもんだね。最低限のプロセスはこんなものかな。

あとはカメラとかオブジェクトを x / y / z 座標のプロパティでいじればいいし、
外部モデリングデータなんかも読み込める。
metasequoia & Blender 使いからするとどっちも取り込めるのでうれしい。
色とか頂点とか正射投影法とかはそれぞれオブジェクトのプロパティをいじって設定する
色やその他についてはまた今度メモる。

timer オブジェクトをはじめて使うので一応メモ。

import flash.utils.Timer;
import flash.events.TimerEvent;
// 引数に間隔(ミリ秒)と繰り返し回数(0は無限)を渡してタイマーオブジェクトを作る
var timer:Timer = new Timer(1000,0);
// TimerEvent にリスナー登録して start() でタイマー開始
timer.addEventListener(TimerEvent.TIMER, ticking);
timer.start();

// 隔秒でやりたい処理を記述
function ticking(ev:TimerEvent):void
{
// イベント終了時に画面を更新(再レンダリング)する。
ev.updateAfterEvent();
}

ポイントは updateAfterEvent() で画面を更新してやると、
フレームレートが小さいときでも更新されるので、イベントが滑らかに見える。
たとえば秒ごとにムービークリップを動かすとか。
目に見えない処理なら必要ないかな?
flvをスクラッチ再生みたくしたいのがどうにもうまく行かない。
キーフレームを増やさないとガクガクになったり、ロードが追いつかなかったり。
ローカルでやってるのに重い。たぶん自分のスキル不足なんだろうけど。
んで、仕方ないので連番jpgをその都度書き換えて動画っぽく見せてやろうかと。
つまりほぼ gif アニメーション。
使うのはローカルだから読み込み遅延はあまり考えなくてもよいし、容量もそれほど気にしない。
長いと異常なファイル数でキツイけど、短いし、フレームレート落して対応する。
とりあえず、画像の読み込みについてメモっておく。

import flash.net.URLRequest;
import flash.display.Loader;

// ファイル名を String型 で代入
var Path:String = "test.jpg";

// Path を渡して URLRequest オブジェクトを作る。
var URI:URLRequest = new URLRequest(Path);

// Loader オブジェクトを作る。まだ読み込まない。
var imgLoader:Loader = new Loader();

// load() に URI を渡して読み込む。
imgLoader.load(URI);

// Loader を表示リストに加える。
addChild(imgLoader);

コレを基本として、URIを書き換えて、URLRequest を作り直して代入し、読み込みなおすのを
EnterFrameで回すと動画っぽくなった。
また、読み込み用の番号を減らして逆再生っぽくしたのも一応動いた。
フレーム番号(ファイル名)を指定してやることで任意の画像を出したり、切り替えたり出来た。
読み込みなおしで切り替え時に画像が消えるかと思ったらそうでもなかった。
最近出番の無いSH8たんで動かして見たら、こま落ちはするものの、
読み込みのタイミングが遅れて、背景が見えるなんてことは無かった。
ひとまずよしとする。
[1]  [2]  [3]  [4
プロフィール
Name :
yukku
カレンダー
05 2024/06 07
S M T W T F S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
ブログ内検索
Twitter
Ads
アクセス解析
忍者ブログ [PR]