2015年11月24日

PolyVoxの使い方についてのメモ

いつの間にか11月下旬ですね…。もう来月で一年が終わってしまうとは困ったものです。
以前の記事でも使っていましたが、PolyVox[1]をMinecraft風に使う場合のメモです。

PolyVoxでは、表面ポリゴン抽出を、マーチングキューブス法を使ってなるべく滑らかな表面を作成する方法と、Minecraftのように立方体が積み重なったような表面を作成する方法のどちらかを選ぶことができます。

CubicSurfaceExtractorWithNormalsでは、ボリュームデータから表面ポリゴンを立方体ベースで作成してくれます。このとき、ポリゴン情報とボリューム格子番号の対応が取れないっぽいのですが、マテリアル番号は格納されているようです。

まず、Minecraft風のボリュームデータでは、各格子が持つデータ1バイト(0〜255)をマテリアル番号として、0を空気、それ以外を物体とします。今回は例題としてMagicaVoxel[2]のサンプルデータを読み込んで、それをボリュームデータとしてそのまま適用しました。

で、ポリゴンデータはチュートリアル[3]にもあるように、下記3行で抽出できます。


  SurfaceMesh<PositionMaterialNormal> mesh;
  CubicSurfaceExtractorWithNormals< SimpleVolume<uint8_t> >
    surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
  surfaceExtractor.execute();

次に、頂点座標やマテリアル番号の参照方法ですが、こちらもチュートリアルを参考にします。

  //Convienient access to the vertices and indices
  const vector<uint32_t>& vecIndices = surfaceMesh.getIndices();
  const vector<PositionMaterialNormal>& vecVertices = surfaceMesh.getVertices();

  for (int i=0; i<vecVertices.size(); i++)
  {
    float p[3], n[3], materialNo;
    p[0] = vecVertices[i].position.getX();
    p[1] = vecVertices[i].position.getY();
    p[2] = vecVertices[i].position.getZ();
    n[0] = vecVertices[i].normal.getX();
    n[1] = vecVertices[i].normal.getY();
    n[2] = vecVertices[i].normal.getZ();
    // float型
    materialNo = vecVertices[i].getMaterial();
  }

あと、テクスチャ座標は取得できない?ようでしたので、面と頂点座標情報から適当に生成して1面に1枚下記画像を張り付けるようにしてみました。
polyvox_test2_003.png

voxファイルにはマテリアル番号と対応する色パレットがありますので、色×テクスチャ色で適当に色付けしています。

実行結果
biome.voxを使用させていただいております。問題があればお知らせください。

 polyvox_test2_001.png polyvox_test2_002.png

まぁMagicaVoxelでPlyやObjで出力できますので、MagicaVoxel対応データをポリゴン化する意味はないですが、現状ではサイズ制限がありますので、大きめのボリュームデータをとりあえずボクセル化したい場合などには使えるかなとは思います。

[1] http://www.volumesoffun.com/polyvox-about/
[2] https://ephtracy.github.io/
[3] http://www.volumesoffun.com/polyvox/documentation/0.2.1/manual/tutorial1.html
web拍手 by FC2
posted by シンドラー at 00:23 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする