1. Kinect + openframeworks でモーションキャプチャ、Flash(Away3D)で再生する (2)

      1) kinect + openframeworks でキャプチャ、csv で保存・サーバに送信 2) flashでcsvをダウンロード、再生 3) openframeworks で再生 2回目です。今回はキャプチャしたものをAway3Dで動かしてみます。 再掲。 http://clwkct.net/kinect/ URLLoaderでoFからアップロードしたcsvをダウンロード、値についてはsplitして配列にいれときます。 ここからが本編ですね。コードを見るのが早そうです。 まずこんなクラスをつくっときます。




    package
    {
    import away3d.containers.ObjectContainer3D;
    import away3d.primitives.WireframeCube;
    import flash.geom.Vector3D;
    import Constants;
    /**
    * ...
    * @author Takeya Hikage
    */
    public class Limb extends ObjectContainer3D
    {

    private var _w:Number = 30;
    private var _h:Number = 250;
    private var _d:Number = 30;
    private var _cube:WireframeCube;
    private var _joint:String;

    public function Limb(joint:String)
    {
    _joint = joint;
    var top:WireframeCube = new WireframeCube(10, 10, 10);//始点の確認用
    addChild(top);

    _cube = new WireframeCube(_w, _h, _d);
    _cube.x = - _w / 2;
    _cube.y = - _h / 2;
    _cube.z = _d / 2;

    addChild(_cube);
    }

    private function transformLimb(elements:Vector.<Number>):void {
    var vec:Vector.<Number> = transform.rawData;

    // elementsのほうを並び替えて入れます
    // 0 , 3 , 6
    // 1 , 4 , 7
    // 2 , 5 , 8

    vec[0] = elements[0];
    vec[1] = elements[3];
    vec[2] = elements[6];
    vec[4] = elements[1];
    vec[5] = elements[4];
    vec[6] = elements[7];
    vec[8] = elements[2];
    vec[9] = elements[5];
    vec[10] = elements[8];
    transform.rawData = vec;

    }

    public function update(orientation:Vector.<Number>,position:Vector.<Number>):void {

    transformLimb(orientation);//回転をセット

    //それぞれのjointごとに向きをあわせる。回転をセットした後にやってあげる必要があります。
    rotate(Vector3D.X_AXIS, 180);

    if (_joint == Constants.JOINT_NECK) {

    }else if(_joint == Constants.JOINT_LEFT_SHOULDER){
    rotate(Vector3D.Z_AXIS , -90);
    rotate(Vector3D.Y_AXIS , 90);
    }else if(_joint == Constants.JOINT_LEFT_ELBOW){
    rotate(Vector3D.Z_AXIS , -90);
    rotate(Vector3D.Y_AXIS , 90);
    }else if(_joint == Constants.JOINT_RIGHT_SHOULDER){
    rotate(Vector3D.Z_AXIS , 90);
    rotate(Vector3D.Y_AXIS , -90);
    }else if(_joint == Constants.JOINT_RIGHT_ELBOW){
    rotate(Vector3D.Z_AXIS , 90);
    rotate(Vector3D.Y_AXIS , -90);
    }else {
    rotate(Vector3D.X_AXIS, 180);
    }

    //座標をセット
    x = position[0];
    y = position[1];
    z = position[2];

    }

    }

    }


    このインスタンスが一つ一つの部位を表しています。 Away3Dのもろもろの設定が終わったらそれぞれの部位をインスタンス化します。ここからはMain.as内です。




    //Limbを登録。この順番はキャプチャしたときの順番に合わせます。Constansはあらかじめ自分で定義したもの。
    _limbs.push(new Limb(Constants.JOINT_TORSO));
    _limbs.push(new Limb(Constants.JOINT_TORSO));
    _limbs.push( new Limb(Constants.JOINT_LEFT_SHOULDER));
    _limbs.push( new Limb(Constants.JOINT_RIGHT_SHOULDER));
    _limbs.push( new Limb(Constants.JOINT_LEFT_ELBOW));
    _limbs.push( new Limb(Constants.JOINT_RIGHT_ELBOW));
    _limbs.push( new Limb(Constants.JOINT_LEFT_HIP));
    _limbs.push( new Limb(Constants.JOINT_RIGHT_HIP));
    _limbs.push( new Limb(Constants.JOINT_LEFT_KNEE));
    _limbs.push( new Limb(Constants.JOINT_RIGHT_KNEE));
    _limbs.push( new Limb(Constants.JOINT_NECK));


    で、あとはEvent.ENTER_FRAMEでまわします。Limbクラスのupdateメソッドにあるとおり、ここでそれぞれのjointの座標、回転の値を渡してます。




    private function update():void {
    var firstFrame:int = _cnt * _limbs.length * 2;//*2は、座標と回転を別の行にしてるため。oFで保存したcsvにフォーマットをあわせる

    if (firstFrame + _limbs.length * 2 >= csv.length) {//csvが最後まで行ったら終了。
    _finished = true;
    return;
    }

    for (var i:int = 0 ; i < _limbs.length ; i++ ) {
    var limb:Limb = _limbs[i];
    var frame:int = firstFrame + i * 2;
    var position:Vector.<Number> = csv[frame];//座標の値の取り出し
    var orientation:Vector.<Number> = csv[frame + 1];//回転の値の取り出し
    limb.update(orientation, position);
    }

    _cnt++;
    }

    private function onEnterFrame(e:Event):void {

    if (!_finished) {
    update();
    }

    camera.lookAt(new Vector3D(0, 0, 3000));
    view.render();
    }


    Limbの向きを設定するあたりは↓を見つつ、実際の動きを確かめながらやりました。これはNITEのドキュメントの中にありました。 えっと、どこでダウンロードしたのだったけな…。たしかここのどこかにあります。見つけたら追記します。





    というかんじです。次回は同様にoF上でも動かしてみます。 ソースについてはgithubに・・・と思ったらアカウント作ってなかったので、そのうちにでも。


    Posted by Takeya Hikage on 2013年03月27日
    Categories flash kinect openframeworks