In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

FLARToolkit Cave(洞窟)のピープショー(モノクローム版)

Cave(洞窟)のピープショー(モノクローム版)
Copyright(c) since 2010 Nekyo.
flartoolkit SimpleCube ベースのサンプル
Flarマーカをかざすと、洞窟のピープショーが表示されます。
カラー版は N's Gallery (http://nsgalle.appspot.com) で公開中。
@licence: GPL v3 http://www.gnu.org/licenses/gpl.html
Flar マーカーをさくーしゃさんのサイトから http://saqoosha.net/lab/FLARToolKit/flarlogo-marker.pdf

ビットマップ読み込み用インクルード
/**
 * Copyright Nekyo ( http://wonderfl.net/user/Nekyo )
 * GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
 * Downloaded from: http://wonderfl.net/c/vPZR
 */

// forked from Nekyo's AR アリスのピープショー(モノクローム版)
package {
	/**
	 * Cave(洞窟)のピープショー(モノクローム版)
	 * Copyright(c) since 2010 Nekyo.
	 * flartoolkit SimpleCube ベースのサンプル
	 * Flarマーカをかざすと、洞窟のピープショーが表示されます。
	 * カラー版は N's Gallery (http://nsgalle.appspot.com) で公開中。
	 * @licence: GPL v3 http://www.gnu.org/licenses/gpl.html
	 * Flar マーカーをさくーしゃさんのサイトから http://saqoosha.net/lab/FLARToolKit/flarlogo-marker.pdf
	 */
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;

	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.WireframeMaterial;
	import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.objects.primitives.Cube;

	import org.libspark.flartoolkit.example.PV3DARApp;

	// ビットマップ読み込み用インクルード
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.utils.BitmapMaterialTools;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import flash.display.Bitmap;
	import flash.display.BitmapData;

	import flash.filters.ColorMatrixFilter;

	[SWF(width=640, height=480, backgroundColor=0xffffff, frameRate=30)]

	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.display.Loader;
	import flash.system.LoaderContext;
	import flash.net.navigateToURL;
	import flash.system.Security;
	import flash.system.SecurityPanel;
	import flash.media.Camera;
	
	public class Cave extends PV3DARApp {
		private var _plane:Plane;
		private var _mask:Cube;
		public var bm_bg:Bitmap = null;
		public var bm_side:Bitmap = null;
		public var bm_bottom:Bitmap = null;

		// テクスチャ画像のURL
		private	const tex_url:Array = [
			'http://lh3.ggpht.com/_XAjHEdaLqjE/S82oTtI7wEI/AAAAAAAAAHs/8MROqrOrBKU/bg.png',
			'http://lh5.ggpht.com/_XAjHEdaLqjE/S82oTyPAoOI/AAAAAAAAAHw/wTThzhQLoss/cube-side.png',
			'http://lh6.ggpht.com/_XAjHEdaLqjE/S82oTy01EkI/AAAAAAAAAH0/nlepsTSQq1E/cube-bottom.png',
		];

		// 対象画像のURL
		private	const image_url:Array = [
			'http://lh4.ggpht.com/_XAjHEdaLqjE/S82oJZH5XvI/AAAAAAAAAHU/RgG2BDqzMDs/cave1.png',
			'http://lh5.ggpht.com/_XAjHEdaLqjE/S82oJTpWK9I/AAAAAAAAAHY/QlYEAM-czLk/cave2.png',
			'http://lh3.ggpht.com/_XAjHEdaLqjE/S82oJmmvXqI/AAAAAAAAAHc/hdP8uTOewbQ/cave3.png',
			'http://lh5.ggpht.com/_XAjHEdaLqjE/S82oJjXJ4NI/AAAAAAAAAHg/3Ica47c5720/cave4.png',
			'http://lh6.ggpht.com/_XAjHEdaLqjE/S82oJ5jZ45I/AAAAAAAAAHk/prLNhqKd-5I/cave5.png',
			'http://lh3.ggpht.com/_XAjHEdaLqjE/S82oTtar6hI/AAAAAAAAAHo/8TZ5dZXMcmc/cave6.png',
		];

		/**
		 * コンストラクタ
		 */
		public function Cave() {
			var camera:Camera = Camera.getCamera();
			if (!camera) {
				// これを実行すると wonderfl のキャプチャーがされない。
				Security.showSettings(SecurityPanel.CAMERA);
			} else {
				Wonderfl.capture_delay(5);

				// カメラ補正ファイルとパターン定義ファイルのファイル名を渡して初期化。
				addEventListener(Event.INIT, _onInit);
				init(
					'http://assets.wonderfl.net/static/flar/camera_para.dat',
					'http://assets.wonderfl.net/static/flar/flarlogo.pat'
				);
			}
		}

		/**
		 * テクスチャ画像読み込み完了イベント処理
		 * 外部から読み込まなくちゃいけないので、一工夫が必要。
		 * @param e イベント
		 */
		private function texinitHandler(event:Event):void
		{
			var loader:Loader = event.target.content.parent;
			for (var i:int = 0; i < tex_url.length; i++) {
				switch (loader.contentLoaderInfo.url) {
					case tex_url[0]:
						bm_bg = event.target.content as Bitmap;
						break;
					case tex_url[1]:
						bm_side = event.target.content as Bitmap;
						break;
					case tex_url[2]:
						bm_bottom = event.target.content as Bitmap;
						break;
				}
			}
			if (bm_bg && bm_side && bm_bottom) {
				// 素材が揃ったら初期化する。
				var bg:Bitmap = stage.addChildAt(bm_bg, 0) as Bitmap;
				bg.width = stage.stageWidth;
				bg.height = stage.stageHeight;
				var cmats:BitmapMaterial = new BitmapMaterial(bm_side.bitmapData, true)
				var cmatb:BitmapMaterial = new BitmapMaterial(bm_bottom.bitmapData, true)
								
				// 穴
				var hole:Cube = new Cube(
					new MaterialsList({all: cmats, back: cmatb}),
					98, 210, 98,	// 幅、奥行き、高さ [Notice] マスクより一回り小さくすると、欠けが少なくなる。
					10, 10, 10,		// 分割数 幅、奥行き、高さ
					Cube.ALL,		// 内側から見える面を指定する。(全画面)
					Cube.FRONT		// 外側から見えない面を指定する。(上面)
				);
				_markerNode.addChild(hole);
				
				_mask = new Cube(
					new MaterialsList({all: new ColorMaterial(0x00ff00)}),
					100, 212, 100, 10, 10, 10, Cube.NONE, Cube.FRONT
				);
				_markerNode.addChild(_mask);

				hole.z = _mask.z = - 105;

				_viewport.filters = [
					new ColorMatrixFilter([
						1, 0, 0, 0, 0,
						0, 1, 0, 0, 0,
						0, 0, 1, 0, 0,
						1, -1, 1, 1, 0
					])
				];
			}
		}

		/**
		 * 画像読み込み完了イベント処理
		 * @param e イベント
		 */
		private function initHandler(event:Event):void
		{
			var loader:Loader = event.target.content.parent;
			var depth:int = 0;
			for (var i:int = 0; i < image_url.length; i++) {
				if (image_url[i] == loader.contentLoaderInfo.url) {
					depth = i;
					break;
				}
			}
			
			var bitmap:Bitmap = event.target.content as Bitmap;

			// 単純に読み込んだ画像分、z深度を変えてプレーンを作って貼るだけ。
			var wmat:BitmapMaterial;
			wmat = new BitmapMaterial(bitmap.bitmapData, true);
			_plane = new Plane(wmat, 98, 98);	// 98mm x 98mm。(マーカー1辺 80mmとしたとき。)
			_plane.rotationX = 180;
			_plane.rotationZ =  90;
			_plane.z = (6 - depth) * 30 - 220;	// Z方向のディスタンス(星空じゃない)
			_markerNode.addChild(_plane);		// _markerNode に addChild するとマーカーに追従する。
		}
 
		/**
		 * イニシャライザ
		 * @param e イベント
		 */
		private function _onInit(e:Event):void {
			// 画像をまとめて読み込む。
			// wonderfl に画像を置ければ [Embed が使えるのに...
			var i:int;
			var loader:Loader;
			for (i = 0; i < tex_url.length; i++) {
				loader = new Loader();
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE, texinitHandler);
				loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOerror);
				loader.load(new URLRequest(tex_url[i]), new LoaderContext(true));
			}

			for (i = 0; i < image_url.length; i++) {
				loader = new Loader();
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE, initHandler);
				loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOerror);
				loader.load(new URLRequest(image_url[i]), new LoaderContext(true));
			}

			// ライトの設定。手前、上のほう。
			var light:PointLight3D = new PointLight3D();
			light.x = 0;
			light.y = 1000;
			light.z = -1000;

			stage.addEventListener(MouseEvent.CLICK, _onClick);
		}

		/**
		 * IOエラー
		 * @param	e
		 */
		private function onIOerror(e:IOErrorEvent):void {
			trace("IO Error." + e.toString());
		}

		/**
		 * クリック時の処理
		 * @param e イベント
		 */
		private function _onClick(e:MouseEvent):void {
			// 画面がクリックされたら新規ウィンドウでN'sギャラリーでも開きますか。
			navigateToURL(new URLRequest("http://nsgalle.appspot.com/"), "_blank");
		}
	}
}