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");
}
}
}