三次元日誌 RSSフィード

2010-04-05

[]GLSLマテリアルにもバックカリングが必要だ

ちょっと改造しよう。

改造した

source/blender/src/drawview.c

void drawview3dspace(ScrArea *sa, void *spacedata)

source/blender/src/drawobject.c

draw_object

draw_mesh_object

draw_mesh_fancy

2287行付近

		if(draw_glsl_material(ob, dt)) {
			glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);

			glEnable(GL_CULL_FACE); // この行追加

			dm->drawFacesGLSL(dm, GPU_enable_material);
			if(get_ob_property(ob, "Text"))
				draw_mesh_text(ob, 1);
			GPU_disable_material();

			glFrontFace(GL_CCW);
		}

当初の目的を達成。

単に天球作ったときの操作性が気に入らなかっただけなんだけど。


同じファイルのdrawcameraで

glDisable(GL_CULL_FACE);

しているのが原因で裏面カリングが効いていないようだが、

その後で元に戻していないのはわざとなのだろうか?

違うところの気がする。


無改造Blenderで確認したところ裏面カリングに関しては

  • ○Textured
  • ×Shaded
  • ×Textured+GLSLマテリアル

という結果に。

if文の分岐で通ったりと通らなかったりする

glEnable(GL_CULL_FACE), glDisable(GL_CULL_FACE)

がどこかにあるっぽい。

[]vmdの回転読み込みが分かった

slerpで短い方の弧で補完させるためには2つのクォータニオンの内積が非負になるようにしてやる必要があった。


今フレームと1つ前のフレームの回転クォータニオンの内積をチェックして負だったときにフラグを立てて以降のフレームのクォータニオンを[-w, -x, -y, -z]に反転させてやるとblenderでもうまくいく。次に内積が負だったときに反転フラグを解除する。


ついでに、オイラー角を経由しないで直接クォータニオンを代入する道を探ったのだが、BlenderのMathUtils.Quaternionの挙動が微妙だった。

微妙1.

Quaternion(w, x, y, z)がQuaternion(w, 0, 0, 0)になる。

使い方が違うのか?

微妙2.

q0 # Quaternion(w0, x0, y0, z0)

q1 # Quaternion(w1, x1, y1, z1)

とあるとたぶん

q0 * q1 = q # Quaternion(w0*w1, x0*x1, y0*y1, z0*z1)

のような動き。要素通しの積なんか使い道あるのだろうか?


といわけでvmdインポータがわりと動くようになった。

http://github.com/ousttrue/blender-mmd-importer

参考文献

実例で学ぶゲーム3D数学

実例で学ぶゲーム3D数学

9.4.13 slerp

類書ではこの本が一番実用的だと思う。