Pages

2012年4月15日日曜日

Dance! Dance! Dance! Perfume

GitHubにPerfume降臨

GitHubにperfumeが登場して話題となったのは、確か3月。Perfumeの世界戦略用のWebサイトで公開されたコンピュータグラフィックスによるダンス動画に使用されたモーション・ピクチャー・データと中田ヤスタカの音楽データをGitHubで提供されたのだ。サンプル・プログラムと共に。
忙しくてダウンロードしたままだった。やっと遊んでみることにした。

Perfume Global site
http://www.perfume-global.com/

GitHub perfume-dev
https://github.com/perfume-dev/

ダウンロードしたデータ

ダンスのMotion Picture Data (BVH形式)
  • あーちゃん用 aachan.bvh
  • かしゆか用 kashiyuka.bvh
  • ノッチ用 nocchi.bvh
音楽 nakata yasutaka 様謹製
  • perfume_globalsite_sound.wav
サンプルプログラムは、Processing用のソースをダウンロード。 とりあえず動かしてみる。3人が準備体操しているだけ。なるほど orz

プログラムソースファイル構成
  • p5f_sample.pde -- メインルーチン
  • PBvh.pde -- pvhデータを扱うモデル
  • PvhParser.pde -- PBvhで利用。bvhデータを解析。
  • BvhBone.pde -- PBvhで利用。フレームの位置情報を扱っている?

サンプルプログラムを修正

プログラムソースをみると、dataフォルダに A_test.bvh, B_test.bvh, C_test.bvhのデータがあり、これを読み込んで動かしているようなので早速、ダウンロードしたbvhファイルに入れ替えて再度実行。
おお!動きました。でも音がない。

  1. 入手したbvhファイル、wavファイルをプログラムソース直下のdataフォルダにコピー
  2. p5f_sample.pdeの中のファイル読み込み部分のファイル名を変更

以下の方のブログを参考に minimライブラリを利用してみました。
http://r-dimension.xsrv.jp/classes_j/minim/

サンプルのままでも、面白いのですが、せっかくサンプルソースが公開されているのですから、ちょっとだけ手を入れてみます。
  • 三人のフレームは色を変えてみる
  • フレームの形状をsphere (球)からbox(立方体)に変更
  • フレームの末端、つまり頭、足首、手首を大きくした
  1. // p5f_sample 修正  
  2. import ddf.minim.*; // サウンドライブラリ minimをインポート  
  3. Minim minim;        // 音源クラス用の変数を宣言  
  4. AudioPlayer player; // 演奏クラス用の変数を宣言  
  5.   
  6. BvhParser parserA = new BvhParser();  
  7. PBvh bvh1, bvh2, bvh3;  
  8. public void setup()  
  9. {  
  10.   size( 1280720, P3D );  
  11.   background( 0 );  
  12.   noStroke();  
  13.   frameRate( 30 );  
  14.     
  15.   // dataフォルダからダンスデータを読み込む  
  16.   bvh1 = new PBvh( loadStrings( "aachan.bvh" ) );  
  17.   bvh2 = new PBvh( loadStrings( "kashiyuka.bvh" ) );  
  18.   bvh3 = new PBvh( loadStrings( "nocchi.bvh" ) );  
  19.   
  20.   // sound add この当たりがサウンド操作  
  21.   // 一回鳴らしたきりになっているがどうしたら良いか不明  
  22.   minim = new Minim(this);  
  23.   player = minim.loadFile("Perfume_globalsite_sound.wav");  
  24.   player.play();  
  25.   
  26.   loop();  
  27. }  
  28.   
  29. public void draw()  
  30. {  
  31.   background( 0 );  
  32.   camera((float) mouseX, (float) mouseY, 100.f, (float) (width/2.f), (float) (height/2.f), 0.f, 0.f, 1.f, 0.f);  
  33.   pushMatrix();  
  34.   translate( width/2, height/2 + 1000);  
  35.   scale(-1, -1, -1);  
  36.   bvh1.draw( millis() , 1); //aachan 識別子として Integer値を渡すことにした  
  37.   bvh2.draw( millis() , 2); //kashiyuka  
  38.   bvh3.draw( millis() , 3); //nochi  
  39.   popMatrix();  
  40. }  
  41.   
  42. void stop()  
  43. {  
  44.   player.close();  
  45.   minim.stop();  
  46.   super.stop();  
  47. }  
// p5f_sample 修正
import ddf.minim.*; // サウンドライブラリ minimをインポート
Minim minim;        // 音源クラス用の変数を宣言
AudioPlayer player; // 演奏クラス用の変数を宣言

BvhParser parserA = new BvhParser();
PBvh bvh1, bvh2, bvh3;
public void setup()
{
  size( 1280, 720, P3D );
  background( 0 );
  noStroke();
  frameRate( 30 );
  
  // dataフォルダからダンスデータを読み込む
  bvh1 = new PBvh( loadStrings( "aachan.bvh" ) );
  bvh2 = new PBvh( loadStrings( "kashiyuka.bvh" ) );
  bvh3 = new PBvh( loadStrings( "nocchi.bvh" ) );

  // sound add この当たりがサウンド操作
  // 一回鳴らしたきりになっているがどうしたら良いか不明
  minim = new Minim(this);
  player = minim.loadFile("Perfume_globalsite_sound.wav");
  player.play();

  loop();
}

public void draw()
{
  background( 0 );
  camera((float) mouseX, (float) mouseY, 100.f, (float) (width/2.f), (float) (height/2.f), 0.f, 0.f, 1.f, 0.f);
  pushMatrix();
  translate( width/2, height/2 + 100, 0);
  scale(-1, -1, -1);
  bvh1.draw( millis() , 1); //aachan 識別子として Integer値を渡すことにした
  bvh2.draw( millis() , 2); //kashiyuka
  bvh3.draw( millis() , 3); //nochi
  popMatrix();
}

void stop()
{
  player.close();
  minim.stop();
  super.stop();
}
PBvh.pde ソースだけ、手を入れてみました。
  1. // PBvh.pde の一部  
  2.   public void draw( int ms , int co) // 識別子用のパラメータ co を追加  
  3.   {  
  4.     parser.moveMsTo( ms, 3000 );   
  5.     BvhBone root = parser.getBones().get(0);  
  6.     update(root);  
  7.     draw(co); // protected な drawに間接的に識別子を渡す  
  8.   }  
  9. //  
  10. // 途中 省略  
  11. //  
  12.   protected void draw(int co)  
  13.   {  
  14.     //fill(color(100));  
  15.     // 識別子 co によって、塗りつぶし色を変更している。  
  16.     if(co == 1){  
  17.       fill(127,0,0);  
  18.     }else if(co == 2){  
  19.       fill(0,127,0);  
  20.     }else if(co == 3){  
  21.       fill(0,0,127);  
  22.     }else{  
  23.       fill(color(100));  
  24.     }  
  25.       
  26.     for( BvhBone b : parser.getBones())  
  27.     {  
  28.       pushMatrix();  
  29.       translate( b.absPos.x, b.absPos.y, b.absPos.z);  
  30.       //sphere(2);  
  31.       box(5); // 立方体に変更  
  32.       popMatrix();  
  33.       if (!b.hasChildren()) // 子を持たない。終端のことか。  
  34.       {  
  35.         pushMatrix();  
  36.         translate( b.absEndPos.x, b.absEndPos.y, b.absEndPos.z);  
  37.         //sphere(2);  
  38.         box(25); // でかい立方体に変更  
  39.         popMatrix();  
  40.       }      
  41.     }  
  42.   }  
// PBvh.pde の一部
  public void draw( int ms , int co) // 識別子用のパラメータ co を追加
  {
    parser.moveMsTo( ms, 3000 ); 
    BvhBone root = parser.getBones().get(0);
    update(root);
    draw(co); // protected な drawに間接的に識別子を渡す
  }
//
// 途中 省略
//
  protected void draw(int co)
  {
    //fill(color(100));
    // 識別子 co によって、塗りつぶし色を変更している。
    if(co == 1){
      fill(127,0,0);
    }else if(co == 2){
      fill(0,127,0);
    }else if(co == 3){
      fill(0,0,127);
    }else{
      fill(color(100));
    }
    
    for( BvhBone b : parser.getBones())
    {
      pushMatrix();
      translate( b.absPos.x, b.absPos.y, b.absPos.z);
      //sphere(2);
      box(5); // 立方体に変更
      popMatrix();
      if (!b.hasChildren()) // 子を持たない。終端のことか。
      {
        pushMatrix();
        translate( b.absEndPos.x, b.absEndPos.y, b.absEndPos.z);
        //sphere(2);
        box(25); // でかい立方体に変更
        popMatrix();
      }    
    }
  }
実際はもっと格好良いのだが!
修正したプログラムは、ここでみることが出来ます。appletなので起動まで時間が掛かかりますね。
Perfume Dance sample applet
気になること
  • 音がループしないし、動きと同期していない。
  • もっと、大胆にカスタマイズしたい。youTubeでは既に多くの人が楽しんで凄いことになっている

右手首をくるくると回しながら、三人が立ち位置を入れ替えているところは、何度観てもかわいいなあ