Processingで3Dモデルを描画する

TinkerCADを使うと簡単に3Dモデルを作成できます。せっかく作成したモデルです。Processingで表示してみましょう。

モデルの出力

TinkerCADでモデルを出力するにはエクスポートを実行します。

  1. 今回はシンプルな木のモデルを作ってみました。
    tree
  2. 画面右上のエクスポートボタンを押下します。
    tree1
    OBJ形式かSTL形式化選択する画面が表示されるので、OBJ形式を選択します。ダウンロードが自動的に始まります。

ファイルの修正

tree2
ダウンロードしたファイルはZIP形式なので展開します。その中にobjとmtlという2つのファイルが含まれています。

  • objファイル = 形状データを含むファイル
  • mtlファイル = 色などのデータを含むファイル(マテリアルファイル)

複数のモデルを扱うときに不便なので、今回はtree.obj、tree.mtlとファイル名を変更しました。このときobjファイルはmtlファイルを参照しているので編集する必要があります。objファイルをテキストエディタで開き、先頭にある記述(ファイル名)をmtlファイルの名前と合致するように修正します。


# Object Export From Tinkercad Server 2015

mtllib tree.mtl

先頭のmtlibから始まる行にmtl形式のファイル名を記述するだけです。OBJファイルと、MTLファイルをProcessingのスケッチのdataフォルダの下に保存してください。

Processingでの描画

3DモデルはPShapeオブジェクトとして管理します。

  • loadShape関数を使ってobjファイルを読み込む
  • shape関数で描画する

たったこれだけで3Dモデルが描画されます。

PShape tree;

void setup() {
  size(512, 512, P3D);
  tree = loadShape("tree.obj");
}

void draw() {
  background(0xffffff);
  translate(width/2, height/2);
  lights();
  camera(0,0,100, 0,0,0, 0,1,0);
  shape(tree);
  tree.rotateY(.001);
}

tree5
setupの中でloadShape関数を使いモデルをロードします。draw関数の中では、translate関数で画面の中心に座標系の原点を移動し、shape関数を使ってtreeモデルを描画しています。rotateY関数でゆっくりとモデルを回転しています。おそらく予想してた結果と異なったのではないでしょうか?木が倒れています!

座標系の話

TinkerCADではちゃんと上向きに木を描画したのに、Processingでは手前に倒れていました。なぜでしょうか?これは座標系が異なることが原因です。
tree6
TinkerCADでは上がz座軸ですが、Processingではz軸は奥から手前に向いています。木が倒れてしまったのはこれが理由です。Processingで座標系を変換してもよいのですが、今回はTinkerCADで元のデータの向きを変換することにしました。tree3
データを作成するときに木を手前に倒します。また、幹の底を原点(平面の中心)になるよう平行移動します。

tree7
無事に木が画面中央に立って表示されるようになりました!

木をランダムに配置してみました。

PShape tree;
PVector[] trees = new PVector[20];
float theta = 0;

void setup() {
  size(512, 512, P3D);
  tree = loadShape("tree.obj");
  for (int i = 0; i < 20; i++) {
    trees[i] = new PVector(random(-200,200), 0, random(-200,200));
  }
}

void draw() {
  background(0);
  translate(width/2, height/2+100);
  fill(100, 50, 50);
  box(1000, 10, 1000);
  lights();
  theta += 1;
  rotateY(radians(theta));
  for(int i = 0 ; i < 20 ; i++){
    pushMatrix();
    PVector t = trees[i];
    translate(t.x, t.y, t.z);
    shape(tree);
    popMatrix();
  }
}

tree4
Y軸を回転させているため林がくるくると回転します。