2009年1月2日金曜日
跳ねるモデル
どうも、作ったPhysXのActorが安定しない(接触面で跳ねたりする)ので、何が原因なんだろうと模索していたら、Rigid bodyのglobalPoseに不適切な行列をぶち込んでいたからのようだ。入れていた行列は、回転以外にスケーリングの成分も含んでいる行列だったんだが、それがいけなかったっぽい。Mayaで作ったPhysXのCollision volumeモデルを書き出す前に、メニュー内のedit->freeze transformしておいて行列を初期化して対処した。あくまでもglobalPoseなんだなぁ。
2008年12月16日火曜日
2008年11月5日水曜日
スキンメッシュ完成
GLSLを勉強して、とりあえずvertex shaderを利用したスキニングに成功。
非常に動作が軽くなった。まぁ前のが異常すぎただけか。glVertexweightfEXTって命令使うとシェーダー使わなくても良い雰囲気するけど、これはこれでいいね。
ハマっていたことをメモメモ
・vertex shaderだけ使うってのは無理らしい。そのため、適当なfragment shaderも用意する必要がある。
・ハードウェアの制限でvertex shader に渡せるマトリックスが61個?らしい。
・attribute intは、ないっぽい。
明らかにきちんと動くはずなのに動かなかったりとか多い。(多分どこかミスがあるんだろうけど)しかもエラーログ吐かないので困る。GLSLってどうやってデバッグすればいいんだろう。
//GLSLのチュートリアルとか
NeHe
GLSLをつかったOpenGLプログラム
GLSL Tutorial von Lighthouse3D
OpenGL Shading Language Tutorials and Demos
yunoの雑記帳 - GLSL
OpenGL:Codes:Simple GLSL example
非常に動作が軽くなった。まぁ前のが異常すぎただけか。glVertexweightfEXTって命令使うとシェーダー使わなくても良い雰囲気するけど、これはこれでいいね。
ハマっていたことをメモメモ
・vertex shaderだけ使うってのは無理らしい。そのため、適当なfragment shaderも用意する必要がある。
・ハードウェアの制限でvertex shader に渡せるマトリックスが61個?らしい。
・attribute intは、ないっぽい。
明らかにきちんと動くはずなのに動かなかったりとか多い。(多分どこかミスがあるんだろうけど)しかもエラーログ吐かないので困る。GLSLってどうやってデバッグすればいいんだろう。
//GLSLのチュートリアルとか
NeHe
GLSLをつかったOpenGLプログラム
GLSL Tutorial von Lighthouse3D
OpenGL Shading Language Tutorials and Demos
yunoの雑記帳 - GLSL
OpenGL:Codes:Simple GLSL example
2008年10月26日日曜日
Skinned mesh
スキンメッシュのコアの部分をメモ
Colladaを読み込む事で、
バインドポーズ逆行列[i]・Jointの行列[i]・モデルの頂点座標・weight[i]が 取れる。(iはJointのIndex)
バインドポーズの逆行列はINV_BIND_MATRIXってColladaのファイル内に書かれている行列。Jointの行列[i] = (・・・*Joint[i]の親の親の変換行列*Joint[i]の親の変換行列*Joint[i]の変換行列)ってな感じで再帰的に計算する。
//変形後の頂点を得るための式
finalPosition = ∑( weight * JointMatrix[i] * BindPoseInversMatrix[i] * originalPosition );
でボーンを曲げた後の各頂点の位置を計算できる。
ここらへんを参照
http://www.gamedev.net/community/forums/topic.asp?topic_id=392338
http://marupeke296.com/DXG_No27_SkinMeshAnimation.html
http://marupeke296.com/DXG_No28_SkinMeshDrawing.html
ただ、今CPUで無理矢理計算しているので重すぎる。バーテックスシェーダーを使ったスキンメッシュに変えないと。自分のノートパソコンが対応してないようなので、学校のパソコン使わなきゃ。
Colladaを読み込む事で、
バインドポーズ逆行列[i]・Jointの行列[i]・モデルの頂点座標・weight[i]が 取れる。(iはJointのIndex)
バインドポーズの逆行列はINV_BIND_MATRIXってColladaのファイル内に書かれている行列。Jointの行列[i] = (・・・*Joint[i]の親の親の変換行列*Joint[i]の親の変換行列*Joint[i]の変換行列)ってな感じで再帰的に計算する。
//変形後の頂点を得るための式
finalPosition = ∑( weight * JointMatrix[i] * BindPoseInversMatrix[i] * originalPosition );
でボーンを曲げた後の各頂点の位置を計算できる。
ここらへんを参照
http://www.gamedev.net/community/forums/topic.asp?topic_id=392338
http://marupeke296.com/DXG_No27_SkinMeshAnimation.html
http://marupeke296.com/DXG_No28_SkinMeshDrawing.html
ただ、今CPUで無理矢理計算しているので重すぎる。バーテックスシェーダーを使ったスキンメッシュに変えないと。自分のノートパソコンが対応してないようなので、学校のパソコン使わなきゃ。
Colladaファイルの注意点
OpenGLは
float* m[16]={・・・略・・・};
glBegin(GL_POINTS);
glMultMatrixf(m);
glVertexf(x,y,z,1)
glEnd();
上記のコードではこんな行列計算をしている。
(m[0] m[4] m[8] m[12]) (x)
(m[1] m[5] m[9] m[13]) (y)
(m[2] m[6] m[10] m[14]) (z)
(m[3] m[7] m[11] m[15]) (1)
つまり、m[12],m[13],m[14]が平行移動の成分になる。
一方Colladaのファイル内は
m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15
のように書かれている。これが意味する行列計算は
(m0 m1 m2 m3 ) (x)
(m4 m5 m6 m7 ) (y)
(m8 m9 m10 m11) (z)
(m12 m13 m14 m15) (1)
つまり、m3,m7,m11が平行移動の成分となる。
OpenGLで使うときは、転置して保存してやる必要がある。
float* m[16]={・・・略・・・};
glBegin(GL_POINTS);
glMultMatrixf(m);
glVertexf(x,y,z,1)
glEnd();
上記のコードではこんな行列計算をしている。
(m[0] m[4] m[8] m[12]) (x)
(m[1] m[5] m[9] m[13]) (y)
(m[2] m[6] m[10] m[14]) (z)
(m[3] m[7] m[11] m[15]) (1)
つまり、m[12],m[13],m[14]が平行移動の成分になる。
一方Colladaのファイル内は
m0 m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15
のように書かれている。これが意味する行列計算は
(m0 m1 m2 m3 ) (x)
(m4 m5 m6 m7 ) (y)
(m8 m9 m10 m11) (z)
(m12 m13 m14 m15) (1)
つまり、m3,m7,m11が平行移動の成分となる。
OpenGLで使うときは、転置して保存してやる必要がある。
FColladaの基本的な流れ
なんとか、スキンメッシュアニメーションを実装できた。
Colladaが比較的分かりやすいフォーマットだからだろうが、前作ろうとした時は断念したから、できて少しうれしい。
FColladaの使い方の基本的な流れをメモ。
// FCDDocumentに読み込む
FCollada::LoadDocumentFromFile(FCDDocument* document, const wchar_t* ファイル名);
↓
↓
//各要素のライブラリーを読み込む(例としてGeometryとする)
//Colladaのファイルの要素にもlibrary_geometriesとかあるので、それと同じと思えばよい
FCDGeometryLibrary* geolib = document->GetGeometryLibrary();
↓
↓
//エンティティを取る
FCDGeometry* geo = geolib->GetEntity();
↓
↓
必要な情報を抜き出し、保存する。
////////////////////////////////////
//ここまでで部品を読み込んだだけ
////////////////////////////////////
実際にシーン情報が保存されているのはColladaファイル内のlibrary_visual_scenesにある。
// sceneのルートノードを取る
FCDSceneNode* root=document->GetVisualSceneRoot();
↓
↓
各ノードを再帰的に呼び出す。
ルート以下のノードは、先ほど保存した各部品が指定されている。
FCDEntity* entity = node->GetInstance(i)->GetEntity(); //iはインスタンスのIndex
entity->GetDaeId()でIdを調べて、先ほどの読み込んだ部品と結びつける
と、頑張ってFCollada使って読み込んでみたけど、FColladaってもう更新行われないっぽい。
フォーラムにもう更新しませんっぽい事書かれてたし。Collada DOMを使えって事かなぁ。
Colladaが比較的分かりやすいフォーマットだからだろうが、前作ろうとした時は断念したから、できて少しうれしい。
FColladaの使い方の基本的な流れをメモ。
// FCDDocumentに読み込む
FCollada::LoadDocumentFromFile(FCDDocument* document, const wchar_t* ファイル名);
↓
↓
//各要素のライブラリーを読み込む(例としてGeometryとする)
//Colladaのファイルの要素にもlibrary_geometriesとかあるので、それと同じと思えばよい
FCDGeometryLibrary* geolib = document->GetGeometryLibrary();
↓
↓
//エンティティを取る
FCDGeometry* geo = geolib->GetEntity();
↓
↓
必要な情報を抜き出し、保存する。
////////////////////////////////////
//ここまでで部品を読み込んだだけ
////////////////////////////////////
実際にシーン情報が保存されているのはColladaファイル内のlibrary_visual_scenesにある。
// sceneのルートノードを取る
FCDSceneNode* root=document->GetVisualSceneRoot();
↓
↓
各ノードを再帰的に呼び出す。
ルート以下のノードは、先ほど保存した各部品が指定されている。
FCDEntity* entity = node->GetInstance(i)->GetEntity(); //iはインスタンスのIndex
entity->GetDaeId()でIdを調べて、先ほどの読み込んだ部品と結びつける
と、頑張ってFCollada使って読み込んでみたけど、FColladaってもう更新行われないっぽい。
フォーラムにもう更新しませんっぽい事書かれてたし。Collada DOMを使えって事かなぁ。
登録:
投稿 (Atom)