Imaginary Code

from kougaku-navi.net

Processingで手抜きプロジェクションマッピング

プロジェクションマッピングが流行ってるようなので、Processingでさくっと書いてみました。ビデオテクスチャの頂点をマウスで操作して、対象物(家具とか)に投影画像をぴったり合わせるというものです。

プロジェクタ固定、対象物固定な静的シーン限定ですが、実際にやってみると、結構楽しいですよ。扉とか箱にセンサをつけて、それに反応して映像が変化するようにしても面白いですね。

import processing.video.*;
import processing.opengl.*;

Movie mov;            // 動画
int   selected = -1;  // 選択されている頂点
int   pos[][] = {{0,0},{400,0},{400,300},{0,300}}; // 頂点座標

void setup() {
  size( 1024, 768, P2D);              // 画面サイズ(適宜調整)
  mov = new Movie(this,"movie.mov");  // 動画ファイルの読み込み
  mov.loop();                         // 動画ループ再生
}

void draw() {
  background(0);
  mov.read(); // 【2014/09/27】 追記しました。Processing2.2.1で動作を確認。

  // ビデオテクスチャの描画
  beginShape();
    texture(mov);  
    vertex(pos[0][0], pos[0][1], 0, 0);
    vertex(pos[1][0], pos[1][1], mov.width, 0);
    vertex(pos[2][0], pos[2][1], mov.width, mov.height);
    vertex(pos[3][0], pos[3][1], 0, mov.height);
  endShape(CLOSE);

  // マウスによる頂点操作
  if ( mousePressed && selected >= 0 ) {
    pos[selected][0] = mouseX;
    pos[selected][1] = mouseY;
  }
  else {
    float min_d = 20; // この値が頂点への吸着の度合いを決める
    selected = -1;
    for (int i=0; i<4; i++) {
      float d = dist( mouseX, mouseY, pos[i][0], pos[i][1] );
      if ( d < min_d ) {
        min_d = d;
        selected = i;
      }      
    }
  }
  if ( selected >= 0 ) {
    ellipse( mouseX, mouseY, 20, 20 );
  }
}


【2014/09/27】 Processing2.2.1で動かなかったのでコードに1行足しました。あと、最近はkeystoneという便利なライブラリがあるのでこれを使う方がいいかも!