AR Bubbles
マーカーを向けた方向に泡が飛びます。
マーカー:http://saqoosha.net/lab/FLARToolKit/flarlogo-marker.pdf
/**
* Copyright talte ( http://wonderfl.net/user/talte )
* GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
* Downloaded from: http://wonderfl.net/c/cHXm
*/
/*
マーカーを向けた方向に泡が飛びます。
マーカー:http://saqoosha.net/lab/FLARToolKit/flarlogo-marker.pdf
*/
package
{
import flash.display.Sprite
import flash.events.Event
import flash.geom.Vector3D
import flash.media.Camera
import flash.media.Video
import flash.net.URLLoader
import flash.net.URLLoaderDataFormat
import flash.net.URLRequest
import flash.display.Bitmap
import flash.display.BitmapData
import flash.display.PixelSnapping
import org.papervision3d.scenes.Scene3D
import org.papervision3d.view.Viewport3D
import org.papervision3d.cameras.Camera3D
import org.papervision3d.render.LazyRenderEngine
import org.libspark.flartoolkit.support.pv3d.FLARCamera3D
import org.libspark.flartoolkit.core.FLARCode
import org.libspark.flartoolkit.core.param.FLARParam
import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData
import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector
import org.libspark.flartoolkit.core.transmat.FLARTransMatResult
public class main extends Sprite
{
private var scene:Scene3D
private var camera:Camera3D
private var viewport:Viewport3D
private var render:LazyRenderEngine
private var pattern:FLARCode
private var webCamera:Camera
private var video:Video
private var capture:Bitmap
private var raster:FLARRgbRaster_BitmapData
private var detector:FLARSingleMarkerDetector
private var bubbles:Array = new Array() // すべての泡を登録する
public function main()
{
// マーカー設定読み込み
var pat_file:String = "http://assets.wonderfl.net/static/flar/flarlogo.pat"
var loader:URLLoader = new URLLoader
loader.dataFormat = URLLoaderDataFormat.TEXT
loader.addEventListener(Event.COMPLETE, this.onFileLoad)
loader.load(new URLRequest(pat_file))
}
private function onFileLoad(event:Event):void
{
// マーカーパターン
this.pattern = new FLARCode(16, 16)
this.pattern.loadARPatt(URLLoader(event.target).data)
// カメラ画像のサイズ
var capture_width:int = 320
var capture_height:int = 240
// カメラ初期化
this.webCamera = Camera.getCamera()
this.webCamera.setMode(capture_width, capture_height, stage.frameRate)
this.video = new Video(capture_width, capture_height)
this.video.attachCamera(this.webCamera)
this.capture = new Bitmap(new BitmapData(capture_width, capture_height, false, 0), PixelSnapping.AUTO, true)
this.capture.width = stage.stageWidth
this.capture.height = stage.stageHeight
this.addChild(this.capture)
// FLAR初期化
this.raster = new FLARRgbRaster_BitmapData(this.capture.bitmapData)
var cameraParam:FLARParam = new FLARParam
cameraParam.changeScreenSize(capture_width, capture_height)
this.detector = new FLARSingleMarkerDetector(cameraParam, this.pattern, 80)
this.detector.setContinueMode(true)
this.camera = new FLARCamera3D(cameraParam)
// PV3D初期化
this.scene = new Scene3D
this.viewport = new Viewport3D(capture_width, capture_height)
this.viewport.scaleX = stage.stageWidth / capture_width
this.viewport.scaleY = stage.stageHeight / capture_height
this.viewport.x = -4
this.addChild(this.viewport)
this.render = new LazyRenderEngine(this.scene, this.camera, this.viewport)
stage.addEventListener(Event.ENTER_FRAME, this.onEnterFrame)
}
// 更新
private function onEnterFrame(event:Event):void
{
// マーカー検出
if(this.detector.detectMarkerLite(this.raster, 128) && this.detector.getConfidence() > 0.5)
{
// マーカーの情報取得
var matrix:FLARTransMatResult = new FLARTransMatResult
this.detector.getTransformMatrix(matrix)
// 泡生成
var bubble:Bubble = new Bubble(matrix)
// 泡を描画用と制御用に登録
this.scene.addChild(bubble)
this.bubbles.push(bubble)
}
// 泡の制御
var del:Array = new Array // 削除登録用
for each(var b:Bubble in this.bubbles)
{
if(b.move()) // 泡移動など
{
del.push(b) // 消す準備
}
}
for each(b in del) // 泡削除
{
this.scene.removeChild(b)
this.bubbles.splice(this.bubbles.indexOf(b), 1)
}
// 再描画
this.capture.bitmapData.draw(this.video) // カメラ
this.render.render() // 泡
}
}
}
import flash.geom.Vector3D
import org.papervision3d.objects.special.VectorShape3D
import org.papervision3d.objects.special.Graphics3D
import org.papervision3d.materials.special.VectorShapeMaterial
import org.libspark.flartoolkit.core.transmat.FLARTransMatResult
class Bubble extends VectorShape3D
{
private var v:Vector3D = new Vector3D // 速度
// 泡
public function Bubble(mat:FLARTransMatResult)
{
super(new VectorShapeMaterial)
// それらしい色で円を書く
var g:Graphics3D = this.graphics
g.beginFill(HSVtoRGB(Math.random() * 360, Math.random() * 0.3 + 0.4, Math.random() * 0.2 + 0.4), Math.random() * 0.2 + 0.5)
g.drawCircle(0, 0, 5)
g.endFill()
// マーカーの位置に泡を移動
this.x = mat.m03
this.y = -mat.m13
this.z = mat.m23
// マーカーのZ方向へ発射
var r:Vector3D = randomCircle()
r.x = r.x * 4
r.y = r.y * 4
r.z = r.z * 2 + 10 // Zはメインで、適度にばらつかせる
this.v.x = mat.m00 * r.x + mat.m01 * r.y + mat.m02 * r.z
this.v.y = -(mat.m10 * r.x + mat.m11 * r.y + mat.m12 * r.z)
this.v.z = mat.m20 * r.x + mat.m21 * r.y + mat.m22 * r.z
}
// 位置更新
public function move():Boolean
{
// 速度分移動
this.x += this.v.x
this.y += this.v.y
this.z += this.v.z
// 速度減衰
this.v.x *= 0.95
this.v.y *= 0.95
this.v.z *= 0.95
// 適度に速度が無くなったら消すように
return v.x * v.x + v.y * v.y + v.z * v.z < 0.02
}
// HSV→RGB
private static function HSVtoRGB(h:Number, s:Number, v:Number):uint
{
h /= 60
var i:int = int(h)
var f:Number = h - i
var p:Number = v * (1 - s)
var q:Number = v * (1 - s * f)
var t:Number = v * (1 - s * (1 - f))
var r:Number
var g:Number
var b:Number
switch(i) {
case 0 : r=v; g=t; b=p; break;
case 1 : r=q; g=v; b=p; break;
case 2 : r=p; g=v; b=t; break;
case 3 : r=p; g=q; b=v; break;
case 4 : r=t; g=p; b=v; break;
case 5 : r=v; g=p; b=q; break;
}
return (int(r * 256) << 16) | (int(g * 256) << 8) | int(b * 256)
}
// 球内の乱数
private static function randomCircle():Vector3D
{
var r:Number = Math.pow(Math.random(), 1 / 3)
var z:Number = Math.random() * 2 - 1
var d:Number = Math.random() * 2 * Math.PI
var x:Number = r * Math.sqrt(1 - z * z)
return new Vector3D(x * Math.cos(d), x * Math.sin(d), r * z)
}
}