Airkinect & RTMFP DEMO
Kinect, XtionのJOINTデータをAirKinectで取得して、ブラウザのFlashに送信して描画するデモです。
/**
* Copyright linktale ( http://wonderfl.net/user/linktale )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/fdd0
*/
/*
KKinect, XtionのJOINTデータをAirKinectで取得して、ブラウザのFlashに送信して描画するデモです。
1. 以下のOpneNIあるいはMSN SDKのAirをインストールする。各環境にあわせてインストールしてください。
・OpenNI版Airをインストール:http://linktale.net/download/air/airkinectrtmfp1_openni.exe
・MSN SDK版Airをインストール:http://linktale.net/download/air/airkinectrtmfp1_mssdk.exe
2. KinectあるいはXtionを接続して、インストールしたAirを起動する。
3. Wonderflのこのページを開く。
※AirとFlashは同じPCあるいは、同一LAN内のPCで表示してください。
5. KinectでJointを取得する。(Kinectの正面に立てば、自動的に取得されます)
6. 今回はRIGHT_HANDでパーティクルが動くようにしているので、右手を動かす。
7. 右手の動きに合わせて、ブラウザ側のFlashでパーティクルが移動する。
※Airを先に起動していないと動かないかもです。Flash側が反応するまでにちょっと時間差があります。
それでも動かない場合はFlash側を何度かリロードすると動くようになると思います。
詳細はこちら
http://linktale.net/log/as3/airkinect-rtmfp-demo-1-as3/
*/
package
{
import com.bit101.components.*;
import com.flashdynamix.utils.SWFProfiler;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.net.GroupSpecifier;
import flash.net.NetConnection;
import flash.net.NetGroup;
import idv.cjcat.stardust.common.actions.Age;
import idv.cjcat.stardust.common.actions.DeathLife;
import idv.cjcat.stardust.common.actions.ScaleCurve;
import idv.cjcat.stardust.common.clocks.SteadyClock;
import idv.cjcat.stardust.common.initializers.Life;
import idv.cjcat.stardust.common.math.UniformRandom;
import idv.cjcat.stardust.twoD.actions.Accelerate;
import idv.cjcat.stardust.twoD.actions.Move;
import idv.cjcat.stardust.twoD.emitters.Emitter2D;
import idv.cjcat.stardust.twoD.handlers.DisplayObjectHandler;
import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass;
import idv.cjcat.stardust.twoD.initializers.Position;
import idv.cjcat.stardust.twoD.initializers.Velocity;
import idv.cjcat.stardust.twoD.zones.LazySectorZone;
import idv.cjcat.stardust.twoD.zones.SinglePoint;
public class Index extends Sprite {
private const SERVER:String = "rtmfp:";
private var nc:NetConnection;
private var netGroup:NetGroup;
private var groupList:Object = new Object();
private var sequence:uint = 1;
private var textArea:TextArea;
private var emitter:Emitter2D;
private var point:SinglePoint;
public function Index():void {
//SWFProfiler.init(stage, this);
//Wonderfl.capture_delay(10);
Wonderfl.disable_capture();
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event=null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
setComponents();
setEmitters();
connect();
}
private function setComponents():void {
Style.embedFonts = false;
Style.fontName = "_typewriter";
Style.fontSize = 12;
textArea = new TextArea(this, 10, 15);
textArea.width = stage.stageWidth-20;
textArea.height = 50;
}
private function setEmitters():void {
var mc:MovieClip = new MovieClip();
addChild(mc);
var clock: SteadyClock = new SteadyClock(3);
emitter = new Emitter2D(clock);
emitter.particleHandler = new DisplayObjectHandler(mc);
point = new SinglePoint();
//initializer
emitter.addInitializer(new DisplayObjectClass(Circle));
emitter.addInitializer(new Position(point));// パーティクルの発生するエリアを指定
emitter.addInitializer(new Velocity(new LazySectorZone(0.1, 0)));// パーティクルにかかる力を指定
emitter.addInitializer(new Life(new UniformRandom(50, 0))); // パーティクルのライフ(生存)を指定
//actions
emitter.addAction(new Age());// 寿命を有効化
emitter.addAction(new DeathLife());// 消えるを有効化
emitter.addAction(new Accelerate(0.025)); // 加速を有効化
emitter.addAction(new Move());// 移動を有効化
emitter.addAction(new ScaleCurve(3, 3));
}
private function connect():void {
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
nc.connect(SERVER);
}
private function netStatus(e:NetStatusEvent):void {
//write(e.info.code);
switch(e.info.code){
case "NetConnection.Connect.Success":
setupGroup();
break;
case "NetGroup.Connect.Success":
write("nc.nearID:" + nc.nearID);
break;
case "NetGroup.Neighbor.Connect":
write("e.info.peerID:"+e.info.peerID);
break;
case "NetGroup.Neighbor.Disconnect":
break;
case "NetGroup.SendTo.Notify":
if(e.info.message.sequence){
sequence = e.info.message.sequence;
write("sequence:" + e.info.message.sequence);
}else if (e.info.message.jointObject) {
update("x", e.info.message.jointObject.right_hand_x);
update("y", e.info.message.jointObject.right_hand_y);
}
break;
}
}
private function update(name:String, value:int):void {
point[name] = value;
emitter.step();
}
private function send(name:String, val:*):void {
var message:Object = new Object();
message.sender = netGroup.convertPeerIDToGroupAddress(nc.nearID);
message[name] = val;
netGroup.sendToAllNeighbors(message);
}
private function setupGroup():void {
var groupspec:GroupSpecifier = new GroupSpecifier("group/linktale");
groupspec.ipMulticastMemberUpdatesEnabled = true;
groupspec.multicastEnabled = true;
groupspec.addIPMulticastAddress("225.225.0.1:44444"); //19350〜65535
groupspec.serverChannelEnabled = true;
groupspec.postingEnabled = true;
groupspec.routingEnabled = true;
netGroup = new NetGroup(nc, groupspec.groupspecWithAuthorizations());
netGroup.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
}
private function write(text:String):void{
textArea.text += text+"\n";
}
}
}
import flash.display.Sprite;
class Circle extends Sprite {
public function Circle() {
var size:uint = 5;
graphics.beginFill(0xdd6666, 0.35);
graphics.drawCircle(0, 0, size);
graphics.beginFill(0xdd6666, 1.0);
graphics.drawCircle(0, 0, size/2);
}
}