2009年7月7日火曜日

UVマッピングとか



Blnderで設定したテクスチャの情報もファイルに書き出すようにしました。

OpenGLで画像をテクスチャとして出力する場合は、テクスチャ座標(頂点と画像を位置合わせするための座標)が必要になるんですが、Blenderではこの座標は頂点ではなく面(Face)に格納されているようです。頂点を共有する隣り合った面で異なるテクスチャを使う場合のためでしょうか。ともかく、フェースの行を次のようなフォーマットにして、テクスチャ座標も出力するようにしました。
F マテリアル番号 頂点数 [頂点番号1 頂点番号2 頂点番号3 ...] [画像ファイル番号] [UV座標1 UV座標2 UV座標3 ...]

UV座標というのがテクスチャ座標のことです。その前の画像ファイル番号は、テクスチャで使う画像ファイルの番号です。画像ファイルは、次のようなI(ImageのI)という識別子の行に出力するようにしました。
I 画像ファイル名

この行の出現回数だけ画像番号が0, 1, 2...と増えていきます。今回は画像1つだけですが。

Pythonスクリプトは次のような感じになります。

images = [] # list of texture file name
:
# repeat each faces
for f in mesh.faces:
out.write("F %d %d" % (f.mat, len(f.verts)))
for v in f.verts:
out.write(" %d" % v.index)
if mesh.faceUV and f.image:
texName = os.path.split(f.image.filename)[1]
try:
texNum = images.index(texName)
except ValueError:
images.append(texName)
texNum = len(images) - 1
out.write(" %d" % texNum)
for uv in f.uv:
out.write(" %f %f" % (uv[0], uv[1]))
out.write("\n")

# texture image files
for img in images:
out.write("I %s\n" % img)

画像ファイル名は、アプリ側の場所とディレクトリが異なるのでパスは省いてファイル名だけを出力するようにしました。画像ファイル名も面(Face)から取得できるので、各面を処理しながら違う画像が使われていたらそれをリストに格納していき、面の処理が終わったあとにリストに溜めたファイル名を出力するようにしています。うーん、もっとスマートなやり方があるかもしれません。

で、モデルは簡単なんですがサイコロ(もどき)です。ちょっとめんどくさかったので....
BlenderでUVマッピングして保存した画像に、Gimpで数字を描いてやりました。
角の線がちゃんと合ってないんですが、まぁ練習ということで...

出力したデータは次のような感じです。
O Dice 1 8 6
M 0.800000 0.800000 0.800000
V 1.998771 1.000000 -1.000000
V 1.998771 -1.000000 -1.000000
V -0.001229 -1.000000 -1.000000
V -0.001229 1.000000 -1.000000
V 1.998771 0.999999 1.000000
V 1.998770 -1.000001 1.000000
V -0.001229 -1.000000 1.000000
V -0.001229 1.000000 1.000000
F 0 4 0 1 2 3 0 0.673504 0.005739 0.673504 0.255311 0.336261 0.255311 0.336261 0.005739
F 0 4 4 7 6 5 0 0.673504 0.754455 0.336261 0.754455 0.336261 0.504883 0.673504 0.504883
F 0 4 0 4 5 1 0 1.010747 0.754455 0.673504 0.754455 0.673504 0.504883 1.010747 0.504883
F 0 4 1 5 6 2 0 0.673504 0.255311 0.673504 0.504883 0.336261 0.504883 0.336261 0.255311
F 0 4 2 6 7 3 0 -0.000982 0.504883 0.336261 0.504883 0.336261 0.754455 -0.000982 0.754455
F 0 4 4 0 3 7 0 0.673504 0.754455 0.673504 1.004027 0.336261 1.004027 0.336261 0.754455
I dice.png


んーと、今日はもう疲れたのでC++側の方はまた次回に。C++での画像ファイル(dice.png)の読み込みは以前使ったDevILを使いました。前使ったはずなのにほとんど忘れかけてて思い出すのにちょっと手間取りました...う〜ん年はとりたくないもんだ。

0 件のコメント: